ch.WriteLine(DragonsSpineMain.APP_NAME+" ("+DragonsSpineMain.APP_VERSION+") Character Menu");
Yes, completely trivial. More of an oversight than a bug, really; since this code only ran on one
server that I’m aware of, the configurability of the name need not be a priority.
# bug - server fails trying to retrieve 'anonymous' field from the Player table, should be checking# PlayerSettings table.@bugScenario: APP_NAME used in high score list
Given I use the "minimal" database as-is
And I set "APP_NAME" in the config file to "Test HigSco"
And the server executable is started
And I allow time for the server to complete startup
When I log on using a standard account
And I enter the chat
And I issue the high scores command
Then I saw a high score list with application name "Test HigSco"
The bug doesn’t have much to do with this test, but the server does a check to exclude anonymous
players from the high score list:
Unfortunately PC.GetField looks directly in the Player table, which doesn’t actually have an
anonymous field any more. But there’s a helpful method to figure out which
table the field is in:
internalstaticstringgetPlayerTableName(intplayerID,stringfield)// gets the table name that contains player field{try{string[]tableNames={"Player","PlayerSettings"};SqlStoredProceduresp;for(inta=0;a<tableNames.Length;a++){sp=newSqlStoredProcedure("prApp_"+tableNames[a]+"_Select",DataAccess.GetSQLConnection());sp.AddParameter("@playerID",SqlDbType.Int,4,ParameterDirection.Input,playerID);DataTabledt=sp.ExecuteDataTable();foreach(DataColumndcindt.Columns){if(dc.ColumnName==field){Utils.Log("DBPlayer.getPlayerTableName("+playerID+", "+field+") found field in table "+tableNames[a]+".",Utils.LogType.Info);returntableNames[a];}}}Utils.Log("DBPlayer.getPlayerTable("+playerID+", "+field+") Field was not found in any player table.",Utils.LogType.SystemFailure);return"error";}catch(Exceptione){Utils.LogException(e);return"error";}}
(I added the debug at line 42 so that I could verify my fix.) This getPlayerTableName method is
used by the getPlayerField method, so if we just switch to that we’ll be fine:
The interesting bit here is the getPlayerTableName method. It can be assumed that the Player
table was once even more monolithic, and an effort was undertaken to move things out of it. While
that was underway, access was channeled through methods which check multiple tables for a field.
There was an efficiency hit due to additional database calls, but perhaps this was considered the
safest way to proceed.
I’ve certainly written similar things; additional complexity to keep things safe while I reworked
major sections. In my more test-driven development work, I’ve gotten away from this entirely; the
tests keep me safe, and I refactor with wild abandon.
That’s the kind of freedom that should make working on the new server-side code very exciting.
Tomorrow.