1
Fork 0
mirror of https://bitbucket.org/Ioncannon/project-meteor-server.git synced 2025-04-22 12:47:46 +00:00

Finished character creator DB calls, moved DB stuff to Dapper, started work on get characters.

This commit is contained in:
Filip Maj 2015-09-09 00:08:46 -04:00
parent 9dfd6906b9
commit 443212830a
10 changed files with 183 additions and 166 deletions

View file

@ -26,6 +26,13 @@ namespace FFXIVClassic_Lobby_Server
//Instance Stuff
public uint currentUserId = 0;
public uint currentAccount;
//Chara Creation
public string newCharaName;
public uint newCharaPid;
public uint newCharaCid;
public ushort newCharaSlot;
public ushort newCharaWorldId;
public void processIncoming(int bytesIn)

View file

@ -1,5 +1,6 @@
using FFXIVClassic_Lobby_Server.dataobjects;
using MySql.Data.MySqlClient;
using Dapper;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
@ -21,7 +22,7 @@ namespace FFXIVClassic_Lobby_Server
try
{
conn.Open();
MySqlCommand cmd = new MySqlCommand("SELECT * FROM ffxiv_sessions WHERE id = @sessionId AND expiration > NOW()", conn);
MySqlCommand cmd = new MySqlCommand("SELECT * FROM sessions WHERE id = @sessionId AND expiration > NOW()", conn);
cmd.Parameters.AddWithValue("@sessionId", sessionId);
using (MySqlDataReader Reader = cmd.ExecuteReader())
{
@ -35,7 +36,7 @@ namespace FFXIVClassic_Lobby_Server
{ Console.WriteLine(e); }
finally
{
conn.Close();
conn.Dispose();
}
}
return id;
@ -51,7 +52,7 @@ namespace FFXIVClassic_Lobby_Server
conn.Open();
//Check if exists
MySqlCommand cmd = new MySqlCommand("SELECT * FROM ffxiv_characters2 WHERE name=@name AND serverId=@serverId", conn);
MySqlCommand cmd = new MySqlCommand("SELECT * FROM characters WHERE name=@name AND serverId=@serverId", conn);
cmd.Parameters.AddWithValue("@serverId", serverId);
cmd.Parameters.AddWithValue("@name", name);
using (MySqlDataReader Reader = cmd.ExecuteReader())
@ -67,16 +68,15 @@ namespace FFXIVClassic_Lobby_Server
{
MySqlCommand cmd2 = new MySqlCommand();
cmd2.Connection = conn;
cmd2.CommandText = "INSERT INTO ffxiv_characters2(userId, slot, serverId, name, state) VALUES(@userId, @slot, @serverId, @name, 0)";
cmd2.CommandText = "INSERT INTO characters(userId, slot, serverId, name, state) VALUES(@userId, @slot, @serverId, @name, 0)";
cmd2.Prepare();
cmd2.Parameters.AddWithValue("@userId", userId);
cmd2.Parameters.AddWithValue("@slot", slot);
cmd2.Parameters.AddWithValue("@serverId", serverId);
cmd2.Parameters.AddWithValue("@name", name);
cmd2.ExecuteNonQuery();
pid = 1;
cid = 1;
cid = (ushort)cmd2.LastInsertedId;
pid = 0xBABE;
}
else
{
@ -91,14 +91,14 @@ namespace FFXIVClassic_Lobby_Server
}
finally
{
conn.Close();
conn.Dispose();
}
}
return alreadyExists;
}
public static void makeCharacter(uint accountId, String name, Character charaInfo)
public static void makeCharacter(uint accountId, uint cid, CharaInfo charaInfo)
{
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)))
{
@ -107,12 +107,13 @@ namespace FFXIVClassic_Lobby_Server
conn.Open();
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = conn;
cmd.CommandText = "UPDATE ffxiv_characters2 SET data=@encodedInfo WHERE accountId=@accountId AND name=@name";
cmd.CommandText = "UPDATE characters SET state=3, charaInfo=@encodedInfo WHERE userId=@userId AND id=@cid";
cmd.Prepare();
cmd.Parameters.AddWithValue("@accountId", accountId);
cmd.Parameters.AddWithValue("@name", name);
cmd.Parameters.AddWithValue("@encodedInfo", JsonConvert.SerializeObject(charaInfo));
cmd.Parameters.AddWithValue("@userId", accountId);
cmd.Parameters.AddWithValue("@cid", cid);
string json = JsonConvert.SerializeObject(charaInfo);
cmd.Parameters.AddWithValue("@encodedInfo", json);
cmd.ExecuteNonQuery();
}
@ -122,7 +123,7 @@ namespace FFXIVClassic_Lobby_Server
}
finally
{
conn.Close();
conn.Dispose();
}
}
}
@ -136,7 +137,7 @@ namespace FFXIVClassic_Lobby_Server
conn.Open();
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = conn;
cmd.CommandText = "UPDATE ffxiv_characters2 SET name=@name WHERE id=@cid";
cmd.CommandText = "UPDATE characters SET name=@name WHERE id=@cid";
cmd.Prepare();
cmd.Parameters.AddWithValue("@cid", characterId);
cmd.Parameters.AddWithValue("@name", newName);
@ -149,7 +150,7 @@ namespace FFXIVClassic_Lobby_Server
}
finally
{
conn.Close();
conn.Dispose();
}
}
}
@ -163,7 +164,7 @@ namespace FFXIVClassic_Lobby_Server
conn.Open();
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = conn;
cmd.CommandText = "UPDATE ffxiv_characters2 SET state=1 WHERE id=@cid AND name=@name";
cmd.CommandText = "UPDATE characters SET state=1 WHERE id=@cid AND name=@name";
cmd.Prepare();
cmd.Parameters.AddWithValue("@cid", characterId);
cmd.Parameters.AddWithValue("@name", name);
@ -176,61 +177,26 @@ namespace FFXIVClassic_Lobby_Server
}
finally
{
conn.Close();
conn.Dispose();
}
}
}
public static List<World> getServers()
{
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)))
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<World> worldList = new List<World>();
List<World> worldList = null;
try
{
conn.Open();
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = conn;
cmd.CommandText = "SELECT * FROM servers WHERE isActive=true";
cmd.Prepare();
MySqlDataReader Reader = cmd.ExecuteReader();
if (!Reader.HasRows) return worldList;
while (Reader.Read())
{
var id = Reader.GetUInt16("id");
var name = Reader.GetString("name");
var address = Reader.GetString("address");
var port = Reader.GetUInt16("port");
var listPosition = Reader.GetUInt16("listPosition");
var numChars = Reader.GetUInt32("numChars");
var maxChars = Reader.GetUInt32("maxChars");
var isActive = Reader.GetBoolean("isActive");
if (isActive)
{
World world = new World();
world.id = id;
world.name = name;
world.address = address;
world.port = port;
world.listPosition = listPosition;
uint result = (uint)(((float)numChars / (float)maxChars) * (float)100);
world.population = (ushort)result;
world.isActive = isActive;
worldList.Add(world);
}
}
worldList = conn.Query<World>("SELECT * FROM servers WHERE isActive=true").ToList();
}
catch (MySqlException e)
{ }
{ worldList = new List<World>(); }
finally
{
conn.Close();
{
conn.Dispose();
}
return worldList;
}
@ -238,46 +204,13 @@ namespace FFXIVClassic_Lobby_Server
public static World getServer(uint serverId)
{
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)))
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)))
{
World world = null;
try
{
conn.Open();
MySqlCommand cmd = new MySqlCommand();
cmd.Connection = conn;
cmd.CommandText = "SELECT * FROM servers WHERE id='%serverId'";
cmd.Prepare();
cmd.Parameters.AddWithValue("@serverId", serverId);
MySqlDataReader Reader = cmd.ExecuteReader();
if (!Reader.HasRows) return world;
while (Reader.Read())
{
var id = Reader.GetUInt16("id");
var name = Reader.GetString("name");
var address = Reader.GetString("address");
var port = Reader.GetUInt16("port");
var listPosition = Reader.GetUInt16("listPosition");
var numChars = Reader.GetUInt32("numChars");
var maxChars = Reader.GetUInt32("maxChars");
var isActive = Reader.GetBoolean("isActive");
if (isActive)
{
world = new World();
world.id = id;
world.name = name;
world.address = address;
world.port = port;
world.listPosition = listPosition;
uint result = ((numChars / maxChars) * 0xFF) & 0xFF;
world.population = (ushort)result;
world.isActive = isActive;
}
}
world = conn.Query<World>("SELECT * FROM servers WHERE id=@ServerId", new {ServerId = serverId}).SingleOrDefault();
}
catch (MySqlException e)
{
@ -291,5 +224,25 @@ namespace FFXIVClassic_Lobby_Server
}
}
public static List<Character> getCharacters(uint userId)
{
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<Character> charaList = null;
try
{
conn.Open();
charaList = conn.Query<Character>("SELECT * FROM characters WHERE userId=@UserId AND state in (2,3) ORDER BY slot", new { UserId = userId }).ToList();
}
catch (MySqlException e)
{ charaList = new List<Character>(); }
finally
{
conn.Dispose();
}
return charaList;
}
}
}
}

View file

@ -37,6 +37,9 @@
<Reference Include="Cyotek.Collections.Generic.CircularBuffer">
<HintPath>..\packages\Cyotek.CircularBuffer.1.0.0.0\lib\net20\Cyotek.Collections.Generic.CircularBuffer.dll</HintPath>
</Reference>
<Reference Include="Dapper">
<HintPath>..\packages\Dapper.1.42\lib\net45\Dapper.dll</HintPath>
</Reference>
<Reference Include="MySql.Data">
<HintPath>..\packages\MySql.Data.6.9.7\lib\net45\MySql.Data.dll</HintPath>
</Reference>
@ -53,6 +56,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="common\Log.cs" />
<Compile Include="dataobjects\CharaInfo.cs" />
<Compile Include="dataobjects\Retainer.cs" />
<Compile Include="dataobjects\Character.cs" />
<Compile Include="ClientConnection.cs" />

View file

@ -154,13 +154,13 @@ namespace FFXIVClassic_Lobby_Server
{
Console.WriteLine("{0} => Get characters", client.currentUserId == 0 ? client.getAddress() : "User " + client.currentUserId);
sendWorldList(client, packet);
sendWorldList(client, packet);
BasePacket outgoingPacket = new BasePacket("./packets/getCharsPacket.bin");
BasePacket outgoingPacket = new BasePacket("./packets/getChars_wo_chars");
BasePacket.encryptPacket(client.blowfish, outgoingPacket);
client.queuePacket(outgoingPacket);
//sendCharacterList(client, packet);
sendCharacterList(client, packet);
}
private void ProcessSelectCharacter(ClientConnection client, SubPacket packet)
@ -207,9 +207,11 @@ namespace FFXIVClassic_Lobby_Server
uint pid = 0, cid = 0;
World world = Database.getServer(worldId);
string worldName = null;
if (worldId == 0)
worldId = client.newCharaWorldId;
string worldName = null;
World world = Database.getServer(worldId);
if (world != null)
worldName = world.name;
@ -233,7 +235,7 @@ namespace FFXIVClassic_Lobby_Server
if (alreadyTaken)
{
ErrorPacket errorPacket = new ErrorPacket(charaReq.sequence, 0xBDB, 0, 13005, "");
ErrorPacket errorPacket = new ErrorPacket(charaReq.sequence, 1003, 0, 13005, ""); //BDB - Chara Name Used, //1003 - Bad Word
SubPacket subpacket = errorPacket.buildPacket();
BasePacket basePacket = BasePacket.createPacket(subpacket, true, false);
BasePacket.encryptPacket(client.blowfish, basePacket);
@ -242,13 +244,25 @@ namespace FFXIVClassic_Lobby_Server
Log.info(String.Format("User {0} => Error; name taken: \"{1}\"", client.currentUserId, charaReq.characterName));
return;
}
else
{
pid = 0;
client.newCharaCid = cid;
client.newCharaSlot = slot;
client.newCharaWorldId = worldId;
client.newCharaName = name;
}
Log.info(String.Format("User {0} => Character reserved \"{1}\"", client.currentUserId, charaReq.characterName));
break;
case 0x02://Make
Character character = Character.EncodedToCharacter(charaReq.characterInfoEncoded);
CharaInfo info = new CharaInfo();
Database.makeCharacter(client.currentUserId, name, character);
Database.makeCharacter(client.currentUserId, client.newCharaCid, info);
pid = 1;
cid = client.newCharaCid;
name = client.newCharaName;
Log.info(String.Format("User {0} => Character created \"{1}\"", client.currentUserId, charaReq.characterName));
break;
@ -299,13 +313,9 @@ namespace FFXIVClassic_Lobby_Server
private void sendCharacterList(ClientConnection client, SubPacket packet)
{
//List<Character> serverList = Database.getServers();
List<Character> characterList = Database.getCharacters(client.currentUserId);
List<Character> charaList = new List<Character>();
charaList.Add(new Character());
charaList.Add(new Character());
CharacterListPacket characterlistPacket = new CharacterListPacket(1, charaList);
CharacterListPacket characterlistPacket = new CharacterListPacket(2, characterList);
List<SubPacket> subPackets = characterlistPacket.buildPackets();
subPackets[0].debugPrintSubPacket();
BasePacket basePacket = BasePacket.createPacket(subPackets, true, false);

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.data>
<DbProviderFactories>
<remove invariant="MySql.Data.MySqlClient" />
<add name="MySQL Data Provider" invariant="MySql.Data.MySqlClient" description=".Net Framework Data Provider for MySQL" type="MySql.Data.MySqlClient.MySqlClientFactory, MySql.Data, Version=6.9.7.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d" />
</DbProviderFactories>
</system.data>
</configuration>

View file

@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FFXIVClassic_Lobby_Server.dataobjects
{
class CharaInfo
{
public uint tribe = 0;
public uint size = 0;
public uint voice = 0;
public uint skinColor = 0;
public uint hairStyle = 0;
public uint hairColor = 0;
public uint eyeColor = 0;
public uint faceType = 0;
public uint faceBrow = 0;
public uint faceEye = 0;
public uint faceIris = 0;
public uint faceNose = 0;
public uint faceMouth = 0;
public uint faceJaw = 0;
public uint faceCheek = 0;
public uint faceOption1 = 0;
public uint faceOption2 = 0;
public uint guardian = 0;
public uint birthMonth = 0;
public uint birthDay = 0;
public uint allegiance = 0;
public uint weapon1 = 0;
public uint weapon2 = 0;
public uint headGear = 0;
public uint bodyGear = 0;
public uint legsGear = 0;
public uint handsGear = 0;
public uint feetGear = 0;
public uint waistGear = 0;
public uint rightEarGear = 0;
public uint leftEarGear = 0;
public uint rightFingerGear = 0;
public uint leftFingerGear = 0;
public byte[] toBytes()
{
byte[] bytes = new byte[0x120];
return bytes;
}
}
}

View file

@ -4,62 +4,23 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FFXIVClassic_Lobby_Server.common;
using FFXIVClassic_Lobby_Server.dataobjects;
namespace FFXIVClassic_Lobby_Server
{
class Character
{
public string name = "Test Test";
public string world = "Test World";
public uint id = 0;
public uint tribe = 0;
public uint size = 0;
public uint voice = 0;
public uint skinColor = 0;
public uint hairStyle = 0;
public uint hairColor = 0;
public uint eyeColor = 0;
public uint faceType = 0;
public uint faceBrow = 0;
public uint faceEye = 0;
public uint faceIris = 0;
public uint faceNose = 0;
public uint faceMouth = 0;
public uint faceJaw = 0;
public uint faceCheek = 0;
public uint faceOption1 = 0;
public uint faceOption2 = 0;
public uint guardian = 0;
public uint birthMonth = 0;
public uint birthDay = 0;
public uint allegiance = 0;
public uint weapon1 = 0;
public uint weapon2 = 0;
public uint headGear = 0;
public uint bodyGear = 0;
public uint legsGear = 0;
public uint handsGear = 0;
public uint feetGear = 0;
public uint waistGear = 0;
public uint rightEarGear = 0;
public uint leftEarGear = 0;
public uint rightFingerGear = 0;
public uint leftFingerGear = 0;
public uint id;
public ushort slot;
public ushort serverId;
public string name;
public ushort state;
public string charaInfo;
public bool isLegacy;
public bool doRename;
public uint currentZoneId;
public byte[] toBytes()
{
byte[] bytes = new byte[0x120];
return bytes;
}
public static String characterToEncoded(Character chara)
public static String characterToEncoded(CharaInfo chara)
{
String charaInfo = System.Convert.ToBase64String(chara.toBytes());
charaInfo.Replace("+", "-");
@ -67,7 +28,7 @@ namespace FFXIVClassic_Lobby_Server
return charaInfo;
}
public static Character EncodedToCharacter(String charaInfo)
public static CharaInfo EncodedToCharacter(String charaInfo)
{
charaInfo.Replace("+", "-");
charaInfo.Replace("/", "_");
@ -77,7 +38,8 @@ namespace FFXIVClassic_Lobby_Server
Console.WriteLine(Utils.ByteArrayToHex(data));
Console.WriteLine("------------Base64 printout------------------");
Character chara = new Character();
CharaInfo chara = new CharaInfo();
return chara;
}
}

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Cyotek.CircularBuffer" version="1.0.0.0" targetFramework="net45" />
<package id="Dapper" version="1.42" targetFramework="net45" />
<package id="MySql.Data" version="6.9.7" targetFramework="net45" />
<package id="Newtonsoft.Json" version="7.0.1" targetFramework="net45" />
</packages>

View file

@ -33,7 +33,7 @@ namespace FFXIVClassic_Lobby_Server.packets
this.command = command;
this.pid = pid;
this.cid = cid;
this.type = 0x400000;
this.type = 0x400017;
this.ticket = ticket;
this.charaName = charaName;
this.worldName = worldName;

View file

@ -41,7 +41,7 @@ namespace FFXIVClassic_Lobby_Server.packets
//Write List Info
binWriter.Write((UInt64)sequence);
binWriter.Write(characterList.Count - totalCount <= MAXPERPACKET ? (byte)(characterList.Count + 1) : (byte)0);
binWriter.Write(characterList.Count - totalCount <= MAXPERPACKET ? (byte)(1) : (byte)0);
//binWriter.Write((byte)1);
binWriter.Write(characterList.Count - totalCount <= MAXPERPACKET ? (UInt32)(characterList.Count - totalCount) : (UInt32)MAXPERPACKET);
binWriter.Write((byte)0);
@ -51,12 +51,26 @@ namespace FFXIVClassic_Lobby_Server.packets
binWriter.Seek(0x10 + (0x1D0 * characterCount), SeekOrigin.Begin);
//Write Entries
World world = Database.getServer(chara.serverId);
string worldname = world == null ? "Unknown" : world.name;
binWriter.Write((uint)0); //???
binWriter.Write((uint)(totalCount + 1)); //Character Id
binWriter.Write((uint)totalCount); //Slot
binWriter.Write((uint)0); //Options (0x01: Service Account not active, 0x72: Change Chara Name)
binWriter.Write((uint)chara.id); //Character Id
binWriter.Write((byte)totalCount); //Slot
byte options = 0;
if (chara.state == 2)
options |= 0x01;
if (chara.doRename)
options |= 0x02;
if (chara.isLegacy)
options |= 0x08;
binWriter.Write((byte)options); //Options (0x01: Service Account not active, 0x72: Change Chara Name)
binWriter.Write((ushort)0);
binWriter.Write((uint)0xF4); //Logged out zone
binWriter.Write(Encoding.ASCII.GetBytes(chara.name.PadRight(0x20, '\0'))); //Name
binWriter.Write(Encoding.ASCII.GetBytes(chara.world.PadRight(0xE, '\0'))); //World Name
binWriter.Write(Encoding.ASCII.GetBytes(worldname.PadRight(0xE, '\0'))); //World Name
binWriter.Write("wAQAAOonIyMNAAAAV3Jlbml4IFdyb25nABwAAAAEAAAAAwAAAAMAAAA_8OADAAHQFAAEAAABAAAAABTQCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGEgAAAAMQAAQCQAAMAsAACKVAAAAPgCAAAAAAAAAAAAAAAAAAAAAAAAAAAAACQAAAAkAwAAAAAAAAAAANvb1M05AQAABBoAAAEABqoiIuIKAAAAcHJ2MElubjAxABEAAABkZWZhdWx0VGVycml0b3J5AAwJAhcABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAIAAAAAAAAAAAAAAAA="); //Appearance Data
characterCount++;