private void LoadDBConfig(string configFile) { var lines = File.ReadLines(configFile) .Select(l => l.Split(' ')) .Select(p => p.Length == 2 ? "" : p[2]) .ToList(); string Username = lines[0]; string Password = lines[1]; string Database = lines[2]; string Host = lines[3]; CharacterDatabase = new MySQL_Connection(MasterThread.Instance, Username, Password, Database, Host); CharacterDBAccessor.InitializeDB(CharacterDatabase); }
public override void AC_OnPacketInbound(Packet packet) { try { if (Server == null) { switch ((ISClientMessages)packet.ReadByte()) { case ISClientMessages.ServerRequestAllocation: { string serverName = packet.ReadString(); LocalServer ls; if (!CenterServer.Instance.LocalServers.TryGetValue(serverName, out ls)) { Program.MainForm.LogAppend("Server doesn't exist in configuration: " + serverName + ". Disconnecting."); Disconnect(); return; } var publicIp = System.Net.IPAddress.Parse(packet.ReadString()); var port = packet.ReadUShort(); Program.MainForm.LogAppend( $"Server connecting... Name: {serverName}, Public IP: {publicIp}, Port {port}"); if (ls.Type == LocalServerType.Game || ls.Type == LocalServerType.Shop) { byte worldid = packet.ReadByte(); if (World.ID != worldid) { Program.MainForm.LogAppend( $"{serverName} disconnected because it didn't have a valid world ID ({worldid})"); Disconnect(); return; } } if (ls.Connected) { if (ls.InMaintenance) { Program.MainForm.LogAppend( $"Server is already connected: {serverName}, but already in maintenance. Disconnecting."); Disconnect(); return; } Program.MainForm.LogAppend( $"Server is already connected: {serverName}. Setting up transfer..."); ls.InMaintenance = true; } Server = ls; Server.PublicIP = publicIp; Server.Port = port; Server.SetConnection(this); Packet pw = new Packet(ISServerMessages.ServerAssignmentResult); pw.WriteBool(Server.InMaintenance); if (ls.Type == LocalServerType.Game || ls.Type == LocalServerType.Shop) { pw.WriteByte(Server.ChannelID); } if (Server.Type == LocalServerType.Game) { Program.MainForm.LogAppend( $"Gameserver assigned! Name {serverName}; Channel ID {Server.ChannelID}"); } else if (Server.Type == LocalServerType.Login) { Program.MainForm.LogAppend("Login connected."); } else if (Server.Type == LocalServerType.Shop) { Program.MainForm.LogAppend($"Shopserver assigned on idx {Server.ChannelID}"); } SendPacket(pw); SendRates(); break; } } } else { var opcode = (ISClientMessages)packet.ReadByte(); switch (opcode) { case ISClientMessages.ServerMigrationUpdate: { if (!Server.InMaintenance) { Program.MainForm.LogAppend("Received ServerMigrationUpdate while not in maintenance!"); break; } var forwardPacket = new Packet(ISServerMessages.ServerMigrationUpdate); forwardPacket.WriteBytes(packet.ReadLeftoverBytes()); // Figure out what way we need to send the packet if (Server.Connection == this) { Server.TransferConnection.SendPacket(forwardPacket); } else { Server.Connection.SendPacket(forwardPacket); } break; } case ISClientMessages.ChangeRates: { Server.RateMobEXP = packet.ReadDouble(); Server.RateMesoAmount = packet.ReadDouble(); Server.RateDropChance = packet.ReadDouble(); break; } case ISClientMessages.ServerSetConnectionsValue: { Server.Connections = packet.ReadInt(); break; } case ISClientMessages.PlayerChangeServer: { string hash = packet.ReadString(); int charid = packet.ReadInt(); byte world = packet.ReadByte(); byte channel = packet.ReadByte(); bool CCing = packet.ReadBool(); var chr = CenterServer.Instance.FindCharacter(charid); Packet pw = new Packet(ISServerMessages.PlayerChangeServerResult); pw.WriteString(hash); pw.WriteInt(charid); bool found = true; LocalServer ls = null; // this will null the key, so if there were two instances CCing, // both would probably get killed. if (RedisBackend.Instance.PlayerIsMigrating(charid, false)) { Program.MainForm.LogAppend("Character {0} tried to CC while already CCing.", charid); pw.WriteInt(0); pw.WriteShort(0); found = false; } else if (channel < 50 && World.GameServers.TryGetValue(channel, out ls) && ls.Connected) { pw.WriteBytes(ls.PublicIP.GetAddressBytes()); pw.WriteUShort(ls.Port); RedisBackend.Instance.SetMigratingPlayer(charid); if (chr != null) { chr.isCCing = true; } if (this.Server.Type == LocalServerType.Login) { CharacterDBAccessor.UpdateRank(charid); } } else if (channel >= 50 && World.ShopServers.TryGetValue((byte)(channel - 50), out ls) && ls.Connected) { pw.WriteBytes(ls.PublicIP.GetAddressBytes()); pw.WriteUShort(ls.Port); RedisBackend.Instance.SetMigratingPlayer(charid); if (chr != null) { chr.isCCing = true; chr.LastChannel = chr.ChannelID; chr.InCashShop = true; } } else { Program.MainForm.LogAppend("Character {0} tried to CC to channel that is not online.", charid); pw.WriteInt(0); pw.WriteShort(0); found = false; } if (CCing && found && chr != null && ls != null) { chr.FriendsList.SaveBuddiesToDb(); chr.isConnectingFromLogin = false; // Give the channel server some info from this server var channelPacket = new Packet(ISServerMessages.PlayerChangeServerData); channelPacket.WriteInt(charid); channelPacket.WriteBytes(packet.ReadLeftoverBytes()); if (Server.ChannelID == channel && Server.InMaintenance) { // Server in maintenance... ls.TransferConnection?.SendPacket(channelPacket); } else { // Changing channels, meh ls.Connection?.SendPacket(channelPacket); } } SendPacket(pw); break; } case ISClientMessages.ServerRegisterUnregisterPlayer: // Register/unregister character { int charid = packet.ReadInt(); bool add = packet.ReadBool(); if (add) { string charname = packet.ReadString(); short job = packet.ReadShort(); byte level = packet.ReadByte(); byte admin = packet.ReadByte(); var character = CenterServer.Instance.AddCharacter(charname, charid, Server.ChannelID, job, level, admin); if (Party.Parties.TryGetValue(character.PartyID, out Party party)) { party.SilentUpdate(character.ID); } else if (character.PartyID != 0) { Program.MainForm.LogAppend("Trying to register a character, but the party was not found??? PartyID: {0}, character ID {1}", character.PartyID, charid); character.PartyID = 0; } var friendsList = character.FriendsList; if (friendsList != null) { friendsList.OnOnlineCC(true, false); friendsList.SendBuddyList(); friendsList.PollRequests(); } } else { bool ccing = packet.ReadBool(); var character = CenterServer.Instance.FindCharacter(charid); if (ccing == false) { character.IsOnline = false; if (Party.Parties.TryGetValue(character.PartyID, out Party party)) { if (party.leader.id == charid) { // Disband the party party.Leave(character); } else { party.SilentUpdate(character.ID); } } character.FriendsList?.OnOnlineCC(true, true); // Fix this. When you log back in, the chat has 2 of you. // Messenger.LeaveMessenger(character.ID); } if (Party.Invites.ContainsKey(character.ID)) { Party.Invites.Remove(character.ID); } } SendUserNoUpdateToLogins(); break; } case ISClientMessages.BroadcastPacketToGameservers: { var p = new Packet(packet.ReadLeftoverBytes()); World.SendPacketToEveryGameserver(p); break; } case ISClientMessages.BroadcastPacketToShopservers: { var p = new Packet(packet.ReadLeftoverBytes()); World.SendPacketToEveryShopserver(p); break; } default: switch (Server.Type) { case LocalServerType.Game: HandleGamePacket(opcode, packet); break; case LocalServerType.Login: HandleLoginPacket(opcode, packet); break; case LocalServerType.Shop: HandleShopPacket(opcode, packet); break; } break; } } } catch (Exception ex) { Program.LogFile.WriteLine("Exception Caught:\r\n{0}", ex.ToString()); //FileWriter.WriteLine(@"etclog\ExceptionCatcher.log", "[Center Server][" + DateTime.Now.ToString() + "] Exception caught: " + ex.Message + Environment.NewLine + Environment.NewLine + "Stacktrace: " + ex.StackTrace, true); //Disconnect(); } }
private void HandleLoginPacket(ISClientMessages opcode, Packet packet) { switch (opcode) { case ISClientMessages.PlayerRequestWorldLoad: { string hash = packet.ReadString(); byte world = packet.ReadByte(); Packet pw = new Packet(ISServerMessages.PlayerRequestWorldLoadResult); pw.WriteString(hash); if (World.ID == world) { World.AddWarning(pw); } else { pw.WriteByte(2); // full load } SendPacket(pw); break; } case ISClientMessages.PlayerRequestChannelStatus: // channel online check { string hash = packet.ReadString(); byte world = packet.ReadByte(); byte channel = packet.ReadByte(); int accountId = packet.ReadInt(); Packet pw = new Packet(ISServerMessages.PlayerRequestChannelStatusResult); pw.WriteString(hash); if (World.ID != world || World.GameServers.TryGetValue(channel, out LocalServer ls) == false || ls.InMaintenance || !ls.Connected) { pw.WriteByte(0x09); // Channel Offline } else { pw.WriteByte(0); pw.WriteByte(channel); try { var ids = CharacterDBAccessor.GetCharacterIdList(accountId).ToList(); pw.WriteByte((byte)ids.Count); foreach (var id in ids) { var ad = CharacterDBAccessor.LoadAvatar(id); var ranking = CharacterDBAccessor.LoadRank(id); ad.Encode(pw); pw.WriteBool(ranking != null); if (ranking != null) { var(worldRank, worldRankMove, jobRank, jobRankMove) = ranking.Value; pw.WriteInt(worldRank); pw.WriteInt(worldRankMove); pw.WriteInt(jobRank); pw.WriteInt(jobRankMove); } } } catch (Exception ex) { Program.MainForm.LogAppend("Error while building packet for characterselect! {0}", ex); _log.Error(ex); pw = new Packet(ISServerMessages.PlayerRequestChannelStatusResult); pw.WriteString(hash); pw.WriteByte(1); } } SendPacket(pw); break; } case ISClientMessages.PlayerDeleteCharacter: { string hash = packet.ReadString(); int accountId = packet.ReadInt(); int charId = packet.ReadInt(); var p = new Packet(ISServerMessages.PlayerDeleteCharacterResult); p.WriteString(hash); p.WriteInt(charId); try { var deleteCharacterResult = CharacterDBAccessor.DeleteCharacter(accountId, charId); p.WriteByte(deleteCharacterResult); if (deleteCharacterResult == 0) { var foundChar = CenterServer.Instance.FindCharacter(charId, false); if (foundChar != null) { if (foundChar.PartyID != 0 && Party.Parties.TryGetValue(foundChar.PartyID, out Party party)) { party.Leave(foundChar); } // Registered, so get rid of it CenterServer.Instance.CharacterStore.Remove(foundChar); } } } catch (Exception ex) { _log.Error(ex); Program.MainForm.LogAppend("Error while deleting character! {0}", ex); p.WriteByte(10); } SendPacket(p); break; } case ISClientMessages.PlayerCreateCharacterNamecheck: { string hash = packet.ReadString(); string charname = packet.ReadString(); var p = new Packet(ISServerMessages.PlayerCreateCharacterNamecheckResult); p.WriteString(hash); p.WriteString(charname); try { p.WriteBool(CharacterDBAccessor.CheckDuplicateID(charname)); } catch (Exception ex) { _log.Error(ex); Program.MainForm.LogAppend("Error while checking for duplicate ID! {0}", ex); p.WriteBool(true); } SendPacket(p); break; } case ISClientMessages.PlayerCreateCharacter: { string hash = packet.ReadString(); int accountId = packet.ReadInt(); byte gender = packet.ReadByte(); string charname = packet.ReadString(); int face = packet.ReadInt(); int hair = packet.ReadInt(); int haircolor = packet.ReadInt(); int skin = packet.ReadInt(); int top = packet.ReadInt(); int bottom = packet.ReadInt(); int shoes = packet.ReadInt(); int weapon = packet.ReadInt(); byte str = packet.ReadByte(); byte dex = packet.ReadByte(); byte intt = packet.ReadByte(); byte luk = packet.ReadByte(); var p = new Packet(ISServerMessages.PlayerCreateCharacterResult); p.WriteString(hash); try { if (CharacterDBAccessor.CheckDuplicateID(charname)) { p.WriteBool(false); } else { int id = CharacterDBAccessor.CreateNewCharacter( accountId, charname, gender, face, hair, haircolor, skin, str, dex, intt, luk, top, bottom, shoes, weapon ); var ad = CharacterDBAccessor.LoadAvatar(id); p.WriteBool(true); ad.Encode(p); } } catch (Exception ex) { _log.Error(ex); Program.MainForm.LogAppend("Error while creating character! {0}", ex); p = new Packet(ISServerMessages.PlayerCreateCharacterResult); p.WriteString(hash); p.WriteBool(false); } SendPacket(p); break; } } }