diff --git a/FFXIVClassic Lobby Server/Database.cs b/FFXIVClassic Lobby Server/Database.cs index d9e7f3be..97840e3d 100644 --- a/FFXIVClassic Lobby Server/Database.cs +++ b/FFXIVClassic Lobby Server/Database.cs @@ -8,6 +8,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using FFXIVClassic_Lobby_Server.common; +using FFXIVClassic_Lobby_Server.utils; namespace FFXIVClassic_Lobby_Server { @@ -123,14 +124,13 @@ namespace FFXIVClassic_Lobby_Server birthDay=@birthDay, birthMonth=@birthMonth, initialTown=@initialTown, - tribe=@tribe, - currentClassJob=@currentClass + tribe=@tribe WHERE userId=@userId AND id=@cid; INSERT INTO characters_appearance - (characterId, baseId, size, voice, skinColor, hairStyle, hairColor, hairHighlightColor, eyeColor, faceType, faceEyebrows, faceEyeShape, faceIrisSize, faceNose, faceMouth, faceFeatures, ears, characteristics, characteristicsColor, mainhand, head, body, hands, legs, feet, waist) + (characterId, baseId, size, voice, skinColor, hairStyle, hairColor, hairHighlightColor, eyeColor, faceType, faceEyebrows, faceEyeShape, faceIrisSize, faceNose, faceMouth, faceFeatures, ears, characteristics, characteristicsColor, mainhand, offhand, head, body, hands, legs, feet, waist) VALUES - (@cid, 4294967295, @size, @voice, @skinColor, @hairStyle, @hairColor, @hairHighlightColor, @eyeColor, @faceType, @faceEyebrows, @faceEyeShape, @faceIrisSize, @faceNose, @faceMouth, @faceFeatures, @ears, @characteristics, @characteristicsColor, @mainhand, @head, @body, @hands, @legs, @feet, @waist) + (@cid, 4294967295, @size, @voice, @skinColor, @hairStyle, @hairColor, @hairHighlightColor, @eyeColor, @faceType, @faceEyebrows, @faceEyeShape, @faceIrisSize, @faceNose, @faceMouth, @faceFeatures, @ears, @characteristics, @characteristicsColor, @mainhand, @offhand, @head, @body, @hands, @legs, @feet, @waist) "; cmd.Parameters.AddWithValue("@userId", accountId); cmd.Parameters.AddWithValue("@cid", cid); @@ -139,7 +139,6 @@ namespace FFXIVClassic_Lobby_Server cmd.Parameters.AddWithValue("@birthMonth", charaInfo.birthMonth); cmd.Parameters.AddWithValue("@initialTown", charaInfo.initialTown); cmd.Parameters.AddWithValue("@tribe", charaInfo.tribe); - cmd.Parameters.AddWithValue("@currentClass", charaInfo.currentClass); cmd.Parameters.AddWithValue("@zoneId", charaInfo.zoneId); cmd.Parameters.AddWithValue("@x", charaInfo.x); @@ -170,66 +169,52 @@ namespace FFXIVClassic_Lobby_Server cmd.Parameters.AddWithValue("@head", charaInfo.head); cmd.Parameters.AddWithValue("@body", charaInfo.body); cmd.Parameters.AddWithValue("@legs", charaInfo.legs); - cmd.Parameters.AddWithValue("@hands", charaInfo.hands); + cmd.Parameters.AddWithValue("@hands", charaInfo.hands); cmd.Parameters.AddWithValue("@feet", charaInfo.feet); cmd.Parameters.AddWithValue("@waist", charaInfo.belt); - + cmd.ExecuteNonQuery(); } catch (MySqlException e) { + conn.Dispose(); + return; } finally { - conn.Dispose(); } - Log.database(String.Format("CID={0} state updated to active(2).", cid)); - } - //Create appearance entry - using (MySqlConnection conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD))) - { + //Create Level and EXP entries try { - conn.Open(); MySqlCommand cmd = new MySqlCommand(); cmd.Connection = conn; - cmd.CommandText = "INSERT INTO appearance(characterId, baseId, tribe, size, voice, skinColor, hairStyle, hairColor, hairHighlightColor, eyeColor, faceType, faceEyebrows, faceEyeShape, faceIrisSize, faceNose, faceMouth, faceFeatures, ears, characteristics, characteristicsColor, mainhand, offhand, head, body, hands, legs, feet, waist, leftFinger, rightFinger, leftEar, rightEar) VALUES(@characterId, @baseId, @tribe, @size, @voice, @skinColor, @hairStyle, @hairColor, @hairHighlightColor, @eyeColor, @faceType, @faceEyebrows, @faceEyeShape, @faceIrisSize, @faceNose, @faceMouth, @faceFeatures, @ears, @characteristics, @characteristicsColor, @mainhand, @offhand, @head, @body, @hands, @legs, @feet, @waist, @leftFinger, @rightFinger, @leftEar, @rightEar)"; + cmd.CommandText = String.Format("INSERT INTO characters_class_levels(characterId, {0}) VALUES(@characterId, 1); INSERT INTO characters_class_exp(characterId) VALUES(@characterId)", CharacterCreatorUtils.GetClassNameForId((short)charaInfo.currentClass)); cmd.Prepare(); cmd.Parameters.AddWithValue("@characterId", cid); - cmd.Parameters.AddWithValue("@baseId", 0xFFFFFFFF); - cmd.Parameters.AddWithValue("@size", charaInfo.appearance.size); - cmd.Parameters.AddWithValue("@voice", charaInfo.appearance.voice); - cmd.Parameters.AddWithValue("@skinColor", charaInfo.appearance.skinColor); - cmd.Parameters.AddWithValue("@hairStyle", charaInfo.appearance.hairStyle); - cmd.Parameters.AddWithValue("@hairColor", charaInfo.appearance.hairColor); - cmd.Parameters.AddWithValue("@hairHighlightColor", charaInfo.appearance.hairHighlightColor); - cmd.Parameters.AddWithValue("@eyeColor", charaInfo.appearance.eyeColor); - cmd.Parameters.AddWithValue("@faceType", charaInfo.appearance.faceType); - cmd.Parameters.AddWithValue("@faceEyebrows", charaInfo.appearance.faceEyebrows); - cmd.Parameters.AddWithValue("@faceEyeShape", charaInfo.appearance.faceEyeShape); - cmd.Parameters.AddWithValue("@faceIrisSize", charaInfo.appearance.faceIrisSize); - cmd.Parameters.AddWithValue("@faceNose", charaInfo.appearance.faceNose); - cmd.Parameters.AddWithValue("@faceMouth", charaInfo.appearance.faceMouth); - cmd.Parameters.AddWithValue("@faceFeatures", charaInfo.appearance.faceFeatures); - cmd.Parameters.AddWithValue("@characteristics", charaInfo.appearance.characteristics); - cmd.Parameters.AddWithValue("@characteristicsColor", charaInfo.appearance.characteristicsColor); - cmd.Parameters.AddWithValue("@mainhand", charaInfo.appearance.mainHand); - cmd.Parameters.AddWithValue("@offhand", charaInfo.appearance.offHand); - cmd.Parameters.AddWithValue("@head", charaInfo.appearance.head); - cmd.Parameters.AddWithValue("@body", charaInfo.appearance.body); - cmd.Parameters.AddWithValue("@hands", charaInfo.appearance.hands); - cmd.Parameters.AddWithValue("@legs", charaInfo.appearance.legs); - cmd.Parameters.AddWithValue("@feet", charaInfo.appearance.feet); - cmd.Parameters.AddWithValue("@waist", charaInfo.appearance.waist); - cmd.Parameters.AddWithValue("@leftFinger", charaInfo.appearance.leftFinger); - cmd.Parameters.AddWithValue("@rightFinger", charaInfo.appearance.rightFinger); - cmd.Parameters.AddWithValue("@leftEar", charaInfo.appearance.leftEar); - cmd.Parameters.AddWithValue("@rightEar", charaInfo.appearance.rightEar); + cmd.ExecuteNonQuery(); + + } + catch (MySqlException e) + { + conn.Dispose(); + return; + } + + //Create Parameter Save + try + { + MySqlCommand cmd = new MySqlCommand(); + cmd.Connection = conn; + cmd.CommandText = String.Format("INSERT INTO characters_parametersave(characterId, hp, hpMax, mp, mpMax, mainSkill, mainSkillLevel) VALUES(@characterId, 1, 1, 1, 1, @mainSkill, 1);", CharacterCreatorUtils.GetClassNameForId((short)charaInfo.currentClass)); + cmd.Prepare(); + + cmd.Parameters.AddWithValue("@characterId", cid); + cmd.Parameters.AddWithValue("@mainSkill", charaInfo.currentClass); cmd.ExecuteNonQuery(); @@ -242,9 +227,9 @@ namespace FFXIVClassic_Lobby_Server { conn.Dispose(); } - - Log.database(String.Format("CID={0} state updated to active(2).", cid)); } + + Log.database(String.Format("CID={0} state updated to active(2).", cid)); } public static bool renameCharacter(uint userId, uint characterId, uint serverId, String newName) @@ -365,45 +350,115 @@ namespace FFXIVClassic_Lobby_Server public static List getCharacters(uint userId) { + List characters = new List(); using (var conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD))) { - List charaList = null; - try - { - conn.Open(); - charaList = conn.Query("SELECT * FROM characters WHERE userId=@UserId AND state = 2 ORDER BY slot", new { UserId = userId }).ToList(); - } - catch (MySqlException e) - { charaList = new List(); } - finally - { - conn.Dispose(); - } - return charaList; - } - } + conn.Open(); + //Load basic info + string query = @" + SELECT + id, + slot, + serverId, + name, + isLegacy, + doRename, + currentZoneId, + guardian, + birthMonth, + birthDay, + initialTown, + tribe, + mainSkill, + mainSkillLevel + FROM characters + INNER JOIN characters_parametersave ON id = characters_parametersave.characterId + WHERE userId = @userId AND state = 2 + ORDER BY slot"; + MySqlCommand cmd = new MySqlCommand(query, conn); + cmd.Parameters.AddWithValue("@userId", userId); + using (MySqlDataReader reader = cmd.ExecuteReader()) + { + while (reader.Read()) + { + Character chara = new Character(); + chara.id = reader.GetUInt32("id"); + chara.slot = reader.GetUInt16("slot"); + chara.serverId = reader.GetUInt16("serverId"); + chara.name = reader.GetString("name"); + chara.isLegacy = reader.GetBoolean("isLegacy"); + chara.doRename = reader.GetBoolean("doRename"); + chara.currentZoneId = reader.GetUInt32("currentZoneId"); + chara.guardian = reader.GetByte("guardian"); + chara.birthMonth = reader.GetByte("birthMonth"); + chara.birthDay = reader.GetByte("birthDay"); + chara.initialTown = reader.GetByte("initialTown"); + chara.tribe = reader.GetByte("tribe"); + chara.currentClass = reader.GetByte("mainSkill"); + //chara.currentJob = ??? + chara.currentLevel = reader.GetInt16("mainSkillLevel"); + characters.Add(chara); + } + } + + } + return characters; + } public static Character getCharacter(uint userId, uint charId) { + Character chara = null; using (var conn = new MySqlConnection(String.Format("Server={0}; Port={1}; Database={2}; UID={3}; Password={4}", ConfigConstants.DATABASE_HOST, ConfigConstants.DATABASE_PORT, ConfigConstants.DATABASE_NAME, ConfigConstants.DATABASE_USERNAME, ConfigConstants.DATABASE_PASSWORD))) { - Character chara = null; - try - { - conn.Open(); - chara = conn.Query("SELECT * FROM characters WHERE id=@CharaId and userId=@UserId", new { UserId = userId, CharaId = charId }).SingleOrDefault(); - } - catch (MySqlException e) - { - } - finally - { - conn.Dispose(); - } + conn.Open(); - return chara; + string query = @" + SELECT + id, + slot, + serverId, + name, + isLegacy, + doRename, + currentZoneId, + guardian, + birthMonth, + birthDay, + initialTown, + tribe, + mainSkill, + mainSkillLevel + FROM characters + INNER JOIN characters_parametersave ON id = characters_parametersave.characterId + WHERE id = @charId"; + + MySqlCommand cmd = new MySqlCommand(query, conn); + cmd.Parameters.AddWithValue("@charId", charId); + using (MySqlDataReader reader = cmd.ExecuteReader()) + { + if (reader.Read()) + { + chara = new Character(); + chara.id = reader.GetUInt32("id"); + chara.slot = reader.GetUInt16("slot"); + chara.serverId = reader.GetUInt16("serverId"); + chara.name = reader.GetString("name"); + chara.isLegacy = reader.GetBoolean("isLegacy"); + chara.doRename = reader.GetBoolean("doRename"); + chara.currentZoneId = reader.GetUInt32("currentZoneId"); + chara.guardian = reader.GetByte("guardian"); + chara.birthMonth = reader.GetByte("birthMonth"); + chara.birthDay = reader.GetByte("birthDay"); + chara.initialTown = reader.GetByte("initialTown"); + chara.tribe = reader.GetByte("tribe"); + chara.currentClass = reader.GetByte("mainSkill"); + //chara.currentJob = ??? + chara.currentLevel = reader.GetInt16("mainSkillLevel"); + } + } } + return chara; } public static Appearance getAppearance(uint charaId) diff --git a/FFXIVClassic Lobby Server/PacketProcessor.cs b/FFXIVClassic Lobby Server/PacketProcessor.cs index ef754006..6f3e8979 100644 --- a/FFXIVClassic Lobby Server/PacketProcessor.cs +++ b/FFXIVClassic Lobby Server/PacketProcessor.cs @@ -230,11 +230,16 @@ namespace FFXIVClassic_Lobby_Server CharaInfo info = CharaInfo.getFromNewCharRequest(charaReq.characterInfoEncoded); //Set Initial Appearance (items will be loaded in by map server) - uint[] classAppearance = CharacterCreatorUtils.getEquipmentForClass(info.currentClass); + uint[] classAppearance = CharacterCreatorUtils.GetEquipmentForClass(info.currentClass); info.weapon1 = classAppearance[0]; info.weapon2 = classAppearance[1]; info.head = classAppearance[7]; - info.body = classAppearance[8]; + + if (classAppearance[8] != 0) + info.body = classAppearance[8]; + else + info.body = CharacterCreatorUtils.GetUndershirtForTribe(info.tribe); + info.legs = classAppearance[9]; info.hands = classAppearance[10]; info.feet = classAppearance[11]; diff --git a/FFXIVClassic Lobby Server/dataobjects/Character.cs b/FFXIVClassic Lobby Server/dataobjects/Character.cs index 610aaa0f..b59c84a7 100644 --- a/FFXIVClassic Lobby Server/dataobjects/Character.cs +++ b/FFXIVClassic Lobby Server/dataobjects/Character.cs @@ -23,13 +23,14 @@ namespace FFXIVClassic_Lobby_Server public byte guardian; public byte birthMonth; public byte birthDay; + public uint currentClass = 3; public uint currentJob = 0; + public int currentLevel = 1; + public byte initialTown; public byte tribe; - public uint currentLevel = 1; - public static CharaInfo EncodedToCharacter(String charaInfo) { charaInfo.Replace("+", "-"); diff --git a/FFXIVClassic Lobby Server/utils/CharacterCreatorUtils.cs b/FFXIVClassic Lobby Server/utils/CharacterCreatorUtils.cs index adec38e8..e1c5f03e 100644 --- a/FFXIVClassic Lobby Server/utils/CharacterCreatorUtils.cs +++ b/FFXIVClassic Lobby Server/utils/CharacterCreatorUtils.cs @@ -10,17 +10,17 @@ namespace FFXIVClassic_Lobby_Server.utils { private static readonly Dictionary equipmentAppearance = new Dictionary { - { 2, new uint[]{60818432,0,0,0,0,0,0,0,10656,10560,1024,25824,6144,0,0,0,0,0,0,0,0,0} }, //PUG + { 2, new uint[]{60818432,60818432,0,0,0,0,0,0,10656,10560,1024,25824,6144,0,0,0,0,0,0,0,0,0} }, //PUG { 3, new uint[]{79692890,0,0,0,0,0,0,0,31776,4448,1024,25824,6144,0,0,0,0,0,0,0,0,0} }, //GLA - { 4, new uint[]{147850310,0,0,0,0,0,0,23713,1184,10016,5472,1152,6144,0,0,0,0,0,0,0,0,0} }, //MRD + { 4, new uint[]{147850310,0,0,0,0,0,0,23713,0,10016,5472,1152,6144,0,0,0,0,0,0,0,0,0} }, //MRD { 7, new uint[]{210764860,236979210,0,0,0,231736320,0,0,9888,9984,1024,25824,6144,0,0,0,0,0,0,0,0,0} }, //ARC { 8, new uint[]{168823858,0,0,0,0,0,0,0,13920,7200,1024,10656,6144,0,0,0,0,0,0,0,0,0} }, //LNC { 22, new uint[]{294650980,0,0,0,0,0,0,0,7744,5472,1024,5504,4096,0,0,0,0,0,0,0,0,0} }, //THM { 23, new uint[]{347079700,0,0,0,0,0,0,0,4448,2240,1024,4416,4096,0,0,0,0,0,0,0,0,0} }, //CNJ - { 29, new uint[]{705692672,0,0,0,0,0,0,0,1184,10016,10656,9632,2048,0,0,0,0,0,0,0,0,0} }, //CRP - { 30, new uint[]{721421372,0,0,0,0,0,0,0,1184,2241,2336,2304,2048,0,0,0,0,0,0,0,0,0} }, //BSM + { 29, new uint[]{705692672,0,0,0,0,0,0,0,0,10016,10656,9632,2048,0,0,0,0,0,0,0,0,0} }, //CRP + { 30, new uint[]{721421372,0,0,0,0,0,0,0,0,2241,2336,2304,2048,0,0,0,0,0,0,0,0,0} }, //BSM { 31, new uint[]{737149962,0,0,0,0,0,0,0,32992,2240,1024,2272,2048,0,0,0,0,0,0,0,0,0} }, //ARM { 32, new uint[]{752878592,0,0,0,0,0,0,0,2368,3424,1024,10656,2048,0,0,0,0,0,0,0,0,0} }, //GSM { 33, new uint[]{768607252,0,0,0,0,0,0,4448,4449,1792,1024,21888,2048,0,0,0,0,0,0,0,0,0} }, //LTW @@ -33,7 +33,7 @@ namespace FFXIVClassic_Lobby_Server.utils { 41, new uint[]{894436372,0,0,0,0,0,0,6400,1184,9984,1024,6529,14336,0,0,0,0,0,0,0,0,0} }, //FSH }; - public static uint[] getEquipmentForClass(uint charClass) + public static uint[] GetEquipmentForClass(uint charClass) { if (equipmentAppearance.ContainsKey(charClass)) return equipmentAppearance[charClass]; @@ -41,6 +41,90 @@ namespace FFXIVClassic_Lobby_Server.utils return null; } + public static string GetClassNameForId(short id) + { + switch (id) + { + case 2: return "pug"; + case 3: return "gla"; + case 4: return "mrd"; + case 7: return "arc"; + case 8: return "lnc"; + case 22: return "thm"; + case 23: return "cnj"; + case 29: return "crp"; + case 30: return "bsm"; + case 31: return "arm"; + case 32: return "gsm"; + case 33: return "ltw"; + case 34: return "wvr"; + case 35: return "alc"; + case 36: return "cul"; + case 39: return "min"; + case 40: return "btn"; + case 41: return "fsh"; + default: return "undefined"; + } + } + + public static uint GetUndershirtForTribe(uint tribe) + { + uint graphicId; + switch (tribe) + { + case 1: + graphicId = 1184; + break; + case 2: + graphicId = 1186; + break; + case 3: + graphicId = 1187; + break; + case 4: + graphicId = 1184; + break; + case 5: + graphicId = 1024; + break; + case 6: + graphicId = 1187; + break; + case 7: + graphicId = 1505; + break; + case 8: + graphicId = 1184; + break; + case 9: + graphicId = 1185; + break; + case 10: + graphicId = 1504; + break; + case 11: + graphicId = 1505; + break; + case 12: + graphicId = 1216; + break; + case 13: + graphicId = 1186; + break; + case 14: + graphicId = 1184; + break; + case 15: + graphicId = 1186; + break; + default: + graphicId = 0; + break; + } + + return graphicId; + } + } }