From b086e2645efa88bb2c32868ec788d5472f88b397 Mon Sep 17 00:00:00 2001 From: Obique Date: Sun, 17 May 2015 13:30:07 -0500 Subject: [PATCH] Fixed CORE-80 'Lock name upon ClientVerifyAndLockNameRequest' --- src/services/player/ZoneService.java | 62 ++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 8 deletions(-) diff --git a/src/services/player/ZoneService.java b/src/services/player/ZoneService.java index 711372c00..bff0abd52 100644 --- a/src/services/player/ZoneService.java +++ b/src/services/player/ZoneService.java @@ -34,7 +34,10 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.Calendar; +import java.util.HashMap; +import java.util.Locale; import java.util.Map; +import java.util.Map.Entry; import java.util.concurrent.ConcurrentHashMap; import main.ProjectSWG; @@ -85,17 +88,20 @@ import services.objects.ObjectManager; import utilities.namegen.SWGNameGenerator; public class ZoneService extends Service { - - private SWGNameGenerator nameGenerator; - private Map profTemplates; - private ClientFactory clientFac; - private NameFilter nameFilter; + + private final Map lockedNames; + private final Map profTemplates; + private final ClientFactory clientFac; + private final NameFilter nameFilter; + private final SWGNameGenerator nameGenerator; private PreparedStatement createCharacter; private PreparedStatement getCharacter; private PreparedStatement getLikeCharacterName; public ZoneService() { + lockedNames = new HashMap(); + profTemplates = new ConcurrentHashMap(); clientFac = new ClientFactory(); nameFilter = new NameFilter("namegen/bad_word_list.txt", "namegen/reserved_words.txt", "namegen/fiction_reserved.txt"); nameGenerator = new SWGNameGenerator(nameFilter); @@ -174,7 +180,7 @@ public class ZoneService extends Service { player.sendPacket(p); System.out.println("[" + player.getUsername() +"] " + player.getCharacterName() + " zoned in"); } - + private void handleClientIdMsg(Player player, ClientIdMsg clientId) { System.out.println("[" + player.getUsername() + "] Connected to the zone server. IP: " + clientId.getAddress() + ":" + clientId.getPort()); sendPacket(player.getNetworkId(), new HeartBeatMessage()); @@ -194,6 +200,11 @@ public class ZoneService extends Service { ErrorMessage err = getNameValidity(name, player.getAccessLevel() != AccessLevel.PLAYER); if (err == ErrorMessage.NAME_APPROVED_MODIFIED) name = nameFilter.cleanName(name); + if (err == ErrorMessage.NAME_APPROVED || err == ErrorMessage.NAME_APPROVED_MODIFIED) { + if (!lockName(name, player)) { + err = ErrorMessage.NAME_DECLINED_IN_USE; + } + } sendPacket(player.getNetworkId(), new ClientVerifyAndLockNameResponse(name, err)); } @@ -379,8 +390,6 @@ public class ZoneService extends Service { } private void loadProfTemplates() { - profTemplates = new ConcurrentHashMap(); - profTemplates.put("crafting_artisan", (ProfTemplateData) clientFac.getInfoFromFile("creation/profession_defaults_combat_brawler.iff")); profTemplates.put("combat_brawler", (ProfTemplateData) clientFac.getInfoFromFile("creation/profession_defaults_combat_brawler.iff")); profTemplates.put("social_entertainer", (ProfTemplateData) clientFac.getInfoFromFile("creation/profession_defaults_social_entertainer.iff")); @@ -390,6 +399,43 @@ public class ZoneService extends Service { profTemplates.put("jedi", (ProfTemplateData) clientFac.getInfoFromFile("creation/profession_defaults_jedi.iff")); } + private boolean lockName(String name, Player player) { + String firstName = name.split(" ", 2)[0].toLowerCase(Locale.ENGLISH); + if (isLocked(firstName)) + return false; + synchronized (lockedNames) { + unlockName(player); + lockedNames.put(firstName, player); + } + return true; + } + + private void unlockName(Player player) { + synchronized (lockedNames) { + String fName = null; + for (Entry e : lockedNames.entrySet()) { + Player locked = e.getValue(); + if (locked != null && locked.equals(player)) { + fName = e.getKey(); + break; + } + } + if (fName != null) + lockedNames.remove(fName); + } + } + + private boolean isLocked(String firstName) { + Player player = null; + synchronized (lockedNames) { + player = lockedNames.get(firstName); + } + if (player == null) + return false; + PlayerState state = player.getPlayerState(); + return state != PlayerState.DISCONNECTED && state != PlayerState.LOGGED_OUT; + } + private Location getStartLocation(String start) { return TerrainZoneInsertion.getInsertionForTerrain(Terrain.TATOOINE); // return TerrainZoneInsertion.getInsertionForArea(Terrain.CORELLIA, -5436, 24, -6211);