From be4b2c0eb81a6c9069b77f733f17f8255bb8feec Mon Sep 17 00:00:00 2001 From: Daniel Boston Date: Sun, 24 Apr 2016 12:55:36 -0400 Subject: [PATCH] Building on collaborative effort from @Maxopoly and @Erocs, pull to address #67 --- NameLayer/pom.xml | 2 +- .../namelayer/database/AssociationList.java | 99 ++++++++++--------- 2 files changed, 51 insertions(+), 50 deletions(-) diff --git a/NameLayer/pom.xml b/NameLayer/pom.xml index 7d1686fa..df02170c 100644 --- a/NameLayer/pom.xml +++ b/NameLayer/pom.xml @@ -6,7 +6,7 @@ vg.civcraft.mc.namelayer NameLayer jar - 2.6.2 + 2.6.3 NameLayer https://github.com/Civcraft/NameLayer/ diff --git a/NameLayerMain/src/vg/civcraft/mc/namelayer/database/AssociationList.java b/NameLayerMain/src/vg/civcraft/mc/namelayer/database/AssociationList.java index 68f26909..11d40a7e 100644 --- a/NameLayerMain/src/vg/civcraft/mc/namelayer/database/AssociationList.java +++ b/NameLayerMain/src/vg/civcraft/mc/namelayer/database/AssociationList.java @@ -7,6 +7,7 @@ import java.util.List; import java.util.Map; import java.util.UUID; +import java.util.logging.Level; import vg.civcraft.mc.namelayer.NameLayerPlugin; @@ -26,16 +27,10 @@ public AssociationList(Database db){ public void genTables(){ // creates the player table // Where uuid and host names will be stored - db.execute("CREATE TABLE IF NOT EXISTS `Name_player` (" + + db.execute("CREATE TABLE IF NOT EXISTS `Name_player` (" + "`uuid` varchar(40) NOT NULL," + "`player` varchar(40) NOT NULL," + "UNIQUE KEY `uuid_player_combo` (`uuid`, `player`));"); - - // this creates the table needed for when a player changes there name to a prexisting name before joining the server - db.execute("create table if not exists playercountnames (" - + "player varchar(40) not null," - + "amount int(10) not null," - + "primary key (player));"); } private String addPlayer; @@ -45,7 +40,7 @@ public void genTables(){ private String getAllPlayerInfo; public void initializeStatements(){ - addPlayer = "call addplayertotable(?, ?)"; // order player name, uuid + addPlayer = "call addplayertotable(?, ?)"; // order player name, uuid getUUIDfromPlayer = "select uuid from Name_player " + "where player=?"; getPlayerfromUUID = "select player from Name_player " + @@ -57,45 +52,40 @@ public void initializeStatements(){ public void initializeProcedures(){ db.execute("drop procedure if exists addplayertotable"); - db.execute("create definer=current_user procedure addplayertotable(" - + "in pl varchar(40), in uu varchar(40)) sql security invoker begin " - + "" - + "declare account varchar(40);" - + "declare nameamount int(10);" - + "" - + "set @@SESSION.max_sp_recursion_depth = 30;" - + "" - + "set nameamount=0;" - + "set nameamount=(select count(*) from Name_player p where p.uuid=uu);" - + "" - + "if (nameamount < 1) then" - + " setName: loop" - + " set account =(select uuid from Name_player p where p.player=pl);" - + " if (account not like uu) then" - + "" - + " if (nameamount > 0) then" - + " set pl = (select concat(SUBSTRING(pl, 1, length(pl)-1)));" - + " end if;" - + "" - + " insert ignore into playercountnames (player, amount) values (pl, 0);" - + "" - + " update playercountnames set amount = nameamount+1 where player=pl;" - + "" - + " set nameamount=(select amount from playercountnames where player=pl);" - + "" - + " set pl = (select concat (pl,nameamount));" - + "" - + " set account =(select uuid from Name_player p where p.player=pl);" - + "" - + " if (account not like uu) then" - + " iterate setName;" - + " end if;" - + " else" - + " insert ignore into Name_player (player, uuid) values (pl, uu);" - + " leave SetName;" - + " end if;" - + "END LOOP setName;" - + "end if;" + db.execute("create definer=current_user procedure" + + "addplayertotable(in pl varchar(16), in uu varchar(36))" + + "sql security invoker" + + "begin" + + " declare account varchar(16);" + + " declare counter int;" + + " declare safe boolean;" + + " set account = pl;" + + " if NOT EXISTS(select uuid from Name_player where uuid=uu) then" + + " --this uuid is not in the table yet" + + " if NOT EXISTS(select uuid from Name_player where player=pl) then" + + " --no other player has this name yet, so we can safely insert it" + + " insert into Name_player(player,uuid) values(pl,uu);" + + " else" + + " --name conflict resolution" + + " set safe = false;" + + " set counter = 1;" + + " REPEAT" + + " IF (LENGTH(pl) + LENGTH(cast(counter as char)) > 16) THEN" + + " set account = CONCAT(SUBSTRING(pl, 0, 16 - length(cast(counter as char))), cast(counter as char));" + + " ELSE" + + " set account = CONCAT(pl, cast(counter as char));" + + " END IF;" + + " IF NOT EXISTS(SELECT uuid FROM Name_player where player=account) THEN" + + " insert into Name_player(player, uuid) values(account, uu);" + + " set safe = true;" + + " ELSE" + + " set counter = counter + 1;" + + " END IF;" + + " UNTIL safe END REPEAT;" + + " end if;" + + " end if;" + + " --return new player name" + + " select account;" + "end"); } @@ -139,13 +129,24 @@ public void addPlayer(String playername, UUID uuid){ try { addPlayer.setString(1, playername); addPlayer.setString(2, uuid.toString()); - addPlayer.execute(); + ResultSet rs = addPlayer.executeQuery(); + String newname = rs.getString(0); + + if (!playername.equals(newname)) { + NameLayerPlugin.log(Level.INFO, "Had to update the name " + playername + " to " + newname + ", because the name already existed"); + } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } + /** + * This appears to be unsafe (doesn't check name uniqueness). + * + * @param newName + * @param uuid + */ public void changePlayer(String newName, UUID uuid) { NameLayerPlugin.reconnectAndReintializeStatements(); PreparedStatement changePlayerName = db.prepareStatement(this.changePlayerName); @@ -160,7 +161,7 @@ public void changePlayer(String newName, UUID uuid) { } /** * This method returns all player info in the table. It is used mainly - * by NameAPI class to prepopulate the maps. + * by NameAPI class to prepopulate the maps. * As such Object[0] will return Map while Object[1] * will return Map */