public List <byte> PullHotkey() { //Make sure this is clear before gathering and sending ourMessage.Clear(); //Packdata in list here and return it to calling method //Get directions integer value and perform technique ourMessage.AddRange(Utility_Funcs.Technique(HotKeyFuncs.OutHoingHotkeyDict[Direction])); //North HK ourMessage.Add(0); ourMessage.AddRange(ConvertHotKey(NMessage, NLabel)); //West HK ourMessage.Add(2); ourMessage.AddRange(ConvertHotKey(WMessage, WLabel)); //East HK ourMessage.Add(4); ourMessage.AddRange(ConvertHotKey(EMessage, ELabel)); //South HK ourMessage.Add(6); ourMessage.AddRange(ConvertHotKey(SMessage, SLabel)); return(ourMessage); }
private static void ProcessDelChar(Session MySession, List <byte> myPacket) { //Passes in packet with ServerID on it, will grab, transform and return ServerID while also removing packet bytes int clientServID = (int)Utility_Funcs.Untechnique(myPacket); //Call SQL delete method to actually process the delete. SQLOperations.DeleteCharacter(clientServID, MySession); }
public List <byte> PullWeaponHotbar() { //Ensure this is empty ourMessage.Clear(); ourMessage.AddRange(Utility_Funcs.Technique(PrimaryHandID)); ourMessage.AddRange(Utility_Funcs.Technique(SecondaryHandID)); ourMessage.AddRange(BitConverter.GetBytes(HotbarName.Length)); ourMessage.AddRange(Encoding.Unicode.GetBytes(HotbarName)); return(ourMessage); }
public List <byte> PullSpell() { //Make sure this is empty before pulling new data ourMessage.Clear(); //Start gathering the data ourMessage.AddRange(Utility_Funcs.Technique(SpellID)); ourMessage.AddRange(Utility_Funcs.Technique(AddedOrder)); ourMessage.AddRange(Utility_Funcs.Technique(OnHotBar)); ourMessage.AddRange(Utility_Funcs.Technique(WhereOnHotBar)); ourMessage.AddRange(Utility_Funcs.Technique(Unk1)); ourMessage.AddRange(Utility_Funcs.Technique(ShowHide)); ourMessage.AddRange(Utility_Funcs.Technique(AbilityLevel)); ourMessage.AddRange(Utility_Funcs.Technique(Unk2)); ourMessage.AddRange(Utility_Funcs.Technique(Unk3)); byte[] MyRange = BitConverter.GetBytes(SpellRange); ourMessage.AddRange(MyRange[2..4]);
///Add a session ack to send to client public static void AddSession(Session MySession, List <byte> OutGoingMessage) { Logger.Info("Adding Session Data"); if (!MySession.remoteMaster) { ///Add first portion of session OutGoingMessage.InsertRange(0, BitConverter.GetBytes(MySession.sessionIDBase)); } else { ///Ack session, first add 2nd portion of Session OutGoingMessage.InsertRange(0, Utility_Funcs.Pack(MySession.sessionIDUp)); ///Add first portion of session OutGoingMessage.InsertRange(0, BitConverter.GetBytes(MySession.sessionIDBase)); } }
public List <byte> PullItem() { ourMessage.Clear(); //Start adding attributes to list for this item ourMessage.AddRange(Utility_Funcs.Technique(StackLeft)); ourMessage.AddRange(Utility_Funcs.Technique(RemainingHP)); ourMessage.AddRange(Utility_Funcs.Technique(Charges)); ourMessage.AddRange(Utility_Funcs.Technique(EquipLocation)); ourMessage.Add(Location); ourMessage.AddRange(BitConverter.GetBytes(InventoryNumber)); ourMessage.AddRange(Utility_Funcs.Technique(ItemID)); ourMessage.AddRange(Utility_Funcs.Technique(ItemCost)); ourMessage.AddRange(Utility_Funcs.Technique(Unk1)); ourMessage.AddRange(Utility_Funcs.Technique(ItemIcon)); ourMessage.AddRange(Utility_Funcs.Technique(Unk2)); ourMessage.AddRange(Utility_Funcs.Technique(Equipslot)); ourMessage.AddRange(Utility_Funcs.Technique(Unk3)); ourMessage.AddRange(Utility_Funcs.Technique(Trade)); ourMessage.AddRange(Utility_Funcs.Technique(Rent)); ourMessage.AddRange(Utility_Funcs.Technique(Unk4)); ourMessage.AddRange(Utility_Funcs.Technique(Attacktype)); ourMessage.AddRange(Utility_Funcs.Technique(Weapondamage)); ourMessage.AddRange(Utility_Funcs.Technique(Unk5)); ourMessage.AddRange(Utility_Funcs.Technique(Levelreq)); ourMessage.AddRange(Utility_Funcs.Technique(Maxstack)); ourMessage.AddRange(Utility_Funcs.Technique(Maxhp)); ourMessage.AddRange(Utility_Funcs.Technique(Duration)); ourMessage.AddRange(Utility_Funcs.Technique(Classuse)); ourMessage.AddRange(Utility_Funcs.Technique(Raceuse)); ourMessage.AddRange(Utility_Funcs.Technique(Procanim)); ourMessage.AddRange(Utility_Funcs.Technique(Lore)); ourMessage.AddRange(Utility_Funcs.Technique(Unk6)); ourMessage.AddRange(Utility_Funcs.Technique(Craft)); ourMessage.AddRange(BitConverter.GetBytes(ItemName.Length)); ourMessage.AddRange(Encoding.Unicode.GetBytes(ItemName)); ourMessage.AddRange(BitConverter.GetBytes(ItemDesc.Length)); ourMessage.AddRange(Encoding.Unicode.GetBytes(ItemDesc)); PullStats(); return(ourMessage); }
public static void AddSessionHeader(Session MySession, List <byte> OutGoingMessage, ushort PacketLength) { uint value = 0; Logger.Info("Adding Session Header"); if (!MySession.Instance) //When server initiates instance with the client, it will use this { value |= 0x80000; } //This would be if we want to cancel the connection... Client handles this in most cases? For now. //if (MySession.CancelConnection) // //{ // value += 0x10000; //} if (MySession.remoteMaster) // Purely a guess.... Something is 0x4000 in this and seems to correspond the initator of the session { value |= 0x04000; } else // Server is not master, seems to always have this when not in control { value |= 0x01000; } if (MySession.hasInstance) // Server always has instance ID, atleast untill we are in world awhile, then it can drop this and the 4 byte instance ID { value |= 0x02000; } //Add bundle length in value |= PacketLength; ///Combine, switch endianness and place into Packet OutGoingMessage.InsertRange(0, Utility_Funcs.Pack(value)); }
public List <byte> PullCharacter() { //Clear List ourMessage.Clear(); //Start pulling data together ourMessage.Add(0); ourMessage.AddRange(BitConverter.GetBytes(Tunaria.Length)); ourMessage.AddRange(Encoding.UTF8.GetBytes(Tunaria)); ourMessage.AddRange(Utility_Funcs.Technique(ServerID)); ourMessage.AddRange(BitConverter.GetBytes(CharName.Length)); ourMessage.AddRange(Encoding.UTF8.GetBytes(CharName)); ourMessage.AddRange(Utility_Funcs.Technique(TClass)); ourMessage.AddRange(Utility_Funcs.Technique(Race)); ourMessage.AddRange(Utility_Funcs.Technique(Level)); ourMessage.AddRange(Utility_Funcs.Technique(TotalXP)); ourMessage.AddRange(Utility_Funcs.Technique(Debt)); ourMessage.Add((byte)Breath); ourMessage.AddRange(Utility_Funcs.Technique(Tunar)); ourMessage.AddRange(Utility_Funcs.Technique(BankTunar)); ourMessage.AddRange(Utility_Funcs.Technique(UnusedTP)); ourMessage.AddRange(Utility_Funcs.Technique(TotalAssignableTP)); ourMessage.AddRange(Utility_Funcs.Technique(World)); ourMessage.AddRange(BitConverter.GetBytes(XCoord)); ourMessage.AddRange(BitConverter.GetBytes(YCoord)); ourMessage.AddRange(BitConverter.GetBytes(ZCoord)); ourMessage.AddRange(BitConverter.GetBytes(Facing)); //Two unknown values must be packed on the end, can be updated later to //include database values when we figure out what it does. ourMessage.AddRange(BitConverter.GetBytes(0.0f)); ourMessage.AddRange(BitConverter.GetBytes(0.0f)); return(ourMessage); }
private void PullStats() { //Gather stats if any exist //Increment counter if if statement true, then add identifier int for stat and then technique and add stat value if (Str > 0) { Counter++; ourStats.Add(0); ourStats.AddRange(Utility_Funcs.Technique(Str)); } if (Sta > 0) { Counter++; ourStats.Add(2); ourStats.AddRange(Utility_Funcs.Technique(Sta)); } if (Agi > 0) { Counter++; ourStats.Add(4); ourStats.AddRange(Utility_Funcs.Technique(Agi)); } if (Dex > 0) { Counter++; ourStats.Add(6); ourStats.AddRange(Utility_Funcs.Technique(Dex)); } if (Wis > 0) { Counter++; ourStats.Add(8); ourStats.AddRange(Utility_Funcs.Technique(Wis)); } if (Int > 0) { Counter++; ourStats.Add(10); ourStats.AddRange(Utility_Funcs.Technique(Int)); } if (Cha > 0) { Counter++; ourStats.Add(12); ourStats.AddRange(Utility_Funcs.Technique(Cha)); } if (HPMax > 0) { Counter++; ourStats.Add(16); ourStats.AddRange(Utility_Funcs.Technique(HPMax)); } if (POWMax > 0) { Counter++; ourStats.Add(20); ourStats.AddRange(Utility_Funcs.Technique(POWMax)); } if (PoT > 0) { Counter++; ourStats.Add(24); ourStats.AddRange(Utility_Funcs.Technique(PoT)); } if (HoT > 0) { Counter++; ourStats.Add(26); ourStats.AddRange(Utility_Funcs.Technique(HoT)); } if (AC > 0) { Counter++; ourStats.Add(28); ourStats.AddRange(Utility_Funcs.Technique(AC)); } if (PR > 0) { Counter++; ourStats.Add(44); ourStats.AddRange(Utility_Funcs.Technique(PR)); } if (DR > 0) { Counter++; ourStats.Add(46); ourStats.AddRange(Utility_Funcs.Technique(DR)); } if (FR > 0) { Counter++; ourStats.Add(48); ourStats.AddRange(Utility_Funcs.Technique(FR)); } if (CR > 0) { Counter++; ourStats.Add(50); ourStats.AddRange(Utility_Funcs.Technique(CR)); } if (LR > 0) { Counter++; ourStats.Add(52); ourStats.AddRange(Utility_Funcs.Technique(LR)); } if (AR > 0) { Counter++; ourStats.Add(54); ourStats.AddRange(Utility_Funcs.Technique(AR)); } //Prepend the stat count ourStats.InsertRange(0, Utility_Funcs.Technique(Counter)); //Add Stats to our List ourMessage.AddRange(ourStats); }
///When a new session is identified, we add this into our endpoint/session list public static void ProcessSession(List <byte> myPacket, IPEndPoint MyIPEndPoint, ushort ClientEndpoint) ///public static void ProcessSession(List<byte> myPacket, bool NewSession) { bool RemoteEndPoint = false; bool NewInstance = false; bool InstanceHeader = false; bool ResetInstance = false; uint val = Utility_Funcs.Unpack(myPacket); //Get's this bundle length int BundleLength = (int)(val & 0x7FF); int value = (int)(val - (val & 0x7FF)); if ((value & 0x80000) != 0) //Requesting instance ack, starting a new session/instance from client { NewInstance = true; } if ((value & 0x02000) != 0) //Has instance in header { InstanceHeader = true; } if ((value & 0x10000) != 0) // reset connection? { ResetInstance = true; } if ((value & 0x0800) != 0) { RemoteEndPoint = true; } //if false, means 4 byte instance header has been removed and only need to read the 3 byte character ID (If server is master //If client is "master", then goes straight into bundle type if (InstanceHeader) { uint SessionIDBase = (uint)(myPacket[3] << 24 | myPacket[2] << 16 | myPacket[1] << 8 | myPacket[0]); myPacket.RemoveRange(0, 4); //If not reset instance, start processing packet data if (ResetInstance) { //Try to find the instance try { ///This finds our session by utilizing endpoints and IPEndPoint info (IP and Port) and drops it DropSession(SessionList.Find(i => Equals(i.clientEndpoint, ClientEndpoint) && Equals(i.MyIPEndPoint, MyIPEndPoint) && Equals(i.sessionIDBase, SessionIDBase))); //Remove the double session information myPacket.RemoveRange(0, 4); if (RemoteEndPoint) { //Remove the 3 byte "Object ID" myPacket.RemoveRange(0, 3); } //if mutliple bundles, process next one if (myPacket.Count() > 10) { //Process next bundle ProcessSession(myPacket, MyIPEndPoint, ClientEndpoint); } } catch { //Just let it die gracefully if not in list // possible for a session to not be in the list if a new connection } } //If new instance, client is initiating this and we know bytes to read else if (NewInstance) { Logger.Info("Checking if session \"exists\""); bool SessionExistence = SessionList.Exists(i => Equals(i.clientEndpoint, ClientEndpoint) && Equals(i.MyIPEndPoint, MyIPEndPoint) && Equals(i.sessionIDBase, SessionIDBase)); ///If it exists, returns to drop this request if (SessionExistence) { ///This "drops" the packet ///If a client from x IPAddress tries to connect with the same endpoint and IP ///and we will drop and wait for clients next endpoint ///Client will do the leg work to "remove" the session return; } ///Create the session Logger.Info("Creating new session for Client"); ///Create our session object instance Session thisSession = new Session(ClientEndpoint, MyIPEndPoint, SessionIDBase); ///Add this sesison to our session list AddMasterSession(thisSession); //Process remaining data ProcessSession(thisSession, myPacket); } //Continue processing session else { //Grab session Session thisSession = SessionList.Find(i => Equals(i.clientEndpoint, ClientEndpoint) && Equals(i.MyIPEndPoint, MyIPEndPoint) && Equals(i.sessionIDBase, SessionIDBase)); if (thisSession == null) { Console.WriteLine("Error Finding Session, maybe transition to memory dump? Ignore for now"); return; } //If server is master/initiated the session we need to remove the 3 byte session Identifier from packet if (thisSession.remoteMaster) { //Could always do an additional check to make sure this matches internally? //Something like //if (thisSession.SessionIDUp == Utility_Funcs.Untechnique(myPacket)) //{//Continue} //else{ //Note exception and fail gracefully?} //Will read our Session Identifier and remove it off the packet for us int SessionIDUp = Utility_Funcs.Untechnique(myPacket); } //If remote master is 0, doesn't really matter... means client is "master" and will not have the 3 byte characterInstanceID ProcessSession(thisSession, myPacket); } } //4 byte header has been removed else { //Assumption would be this must be an ongoing session, so should never expect a new session without the instance header //Grab session //Will this always be correct? Shouldn't have duplicate client endpoints so should be... Session thisSession = SessionList.Find(i => Equals(i.clientEndpoint, ClientEndpoint) && Equals(i.MyIPEndPoint, MyIPEndPoint)); //If server is master/initiated the session we need to remove the 3 byte session Identifier from packet if (thisSession.remoteMaster) { //Could always do an additional check to make sure this matches internally? //Something like //if (thisSession.SessionIDUp == Utility_Funcs.Untechnique(myPacket)) //{//Continue} //else{ //Note exception and fail gracefully?} //Will read our Session Identifier and remove it off the packet for us int SessionIDUp = Utility_Funcs.Untechnique(myPacket); } //If remote master is 0, doesn't really matter... means client is "master" and will not have the 3 byte characterInstanceID ProcessSession(thisSession, myPacket); } }
public static void CreateCharacterList(List <Character> MyCharacterList, Session MySession) { //Holds list of characters pulled from the DB for the AccountID List <byte> CharacterList = new List <byte>(); ///Gets our character count and uses technique to double it CharacterList.AddRange(Utility_Funcs.Technique((byte)MyCharacterList.Count())); //Iterates through each charcter in the list and converts attribute values to packet values foreach (Character character in MyCharacterList) { ///Add the Character name length CharacterList.AddRange(BitConverter.GetBytes((uint)character.CharName.Length)); ///Add character name CharacterList.AddRange(Encoding.ASCII.GetBytes(character.CharName)); ///Add Server ID CharacterList.AddRange(Utility_Funcs.Technique(character.ServerID)); ///Add Model CharacterList.AddRange(Utility_Funcs.Technique(character.ModelID)); ///Add Class CharacterList.AddRange(Utility_Funcs.Technique(character.TClass)); ///Add Race CharacterList.AddRange(Utility_Funcs.Technique(character.Race)); ///Add Level CharacterList.AddRange(Utility_Funcs.Technique(character.Level)); ///Add Hair color CharacterList.AddRange(Utility_Funcs.Technique(character.HairColor)); ///Add Hair Length CharacterList.AddRange(Utility_Funcs.Technique(character.HairLength)); ///Add Hair Style CharacterList.AddRange(Utility_Funcs.Technique(character.HairStyle)); ///Add Face option CharacterList.AddRange(Utility_Funcs.Technique(character.FaceOption)); ///Start processing MyItem foreach (Item MyItem in character.InventoryItems) { ///Use a switch to sift through MyItem and add them properly switch (MyItem.EquipLocation) { ///Helm case 1: character.Helm = (byte)MyItem.Model; character.HelmColor = MyItem.Color; break; ///Robe case 2: character.Robe = (byte)MyItem.Model; character.RobeColor = MyItem.Color; break; ///Gloves case 19: character.Gloves = (byte)MyItem.Model; character.GlovesColor = MyItem.Color; break; ///Chest case 5: character.Chest = (byte)MyItem.Model; character.ChestColor = MyItem.Color; break; ///Bracers case 8: character.Bracer = (byte)MyItem.Model; character.BracerColor = MyItem.Color; break; ///Legs case 10: character.Legs = (byte)MyItem.Model; character.LegsColor = MyItem.Color; break; ///Feet case 11: character.Boots = (byte)MyItem.Model; character.BootsColor = MyItem.Color; break; ///Primary case 12: character.Primary = MyItem.Model; break; ///Secondary case 14: ///If we have a secondary equipped already, puts next secondary into primary slot if (character.Secondary > 0) { character.Primary = MyItem.Model; } ///If no secondary, add to secondary slot else { character.Secondary = MyItem.Model; } break; ///2 Hand case 15: character.Primary = MyItem.Model; break; ///Shield case 13: character.Shield = MyItem.Model; break; ///Bow case 16: character.Primary = MyItem.Model; break; ///Thrown case 17: character.Primary = MyItem.Model; break; ///Held case 18: ///If we have a secondary equipped already, puts next secondary into primary slot if (character.Secondary > 0) { character.Primary = MyItem.Model; } ///If no secondary, add to secondary slot else { character.Secondary = MyItem.Model; } break; default: Logger.Err("Equipment not in list, this may need to be changed"); break; } } ///Add Robe CharacterList.AddRange(BitConverter.GetBytes(character.Robe)); ///Add Primary CharacterList.AddRange(BitConverter.GetBytes(character.Primary)); ///Add Secondary CharacterList.AddRange(BitConverter.GetBytes(character.Secondary)); ///Add Shield CharacterList.AddRange(BitConverter.GetBytes(character.Shield)); ///Add Character animation here, dumby for now CharacterList.AddRange(BitConverter.GetBytes((ushort)0x0004)); ///unknown value? CharacterList.Add((byte)0); ///Chest Model CharacterList.Add(character.Chest); ///uBracer Model CharacterList.Add(character.Bracer); ///Glove Model CharacterList.Add(character.Gloves); ///Leg Model CharacterList.Add(character.Legs); ///Boot Model CharacterList.Add(character.Boots); ///Helm Model CharacterList.Add(character.Helm); ///unknown value? CharacterList.AddRange(BitConverter.GetBytes((uint)0)); ///unknown value? CharacterList.AddRange(BitConverter.GetBytes((ushort)0)); ///unknown value? CharacterList.AddRange(BitConverter.GetBytes(0xFFFFFFFF)); ///unknown value? CharacterList.AddRange(BitConverter.GetBytes(0xFFFFFFFF)); ///unknown value? CharacterList.AddRange(BitConverter.GetBytes(0xFFFFFFFF)); ///Chest color CharacterList.AddRange(BitConverter.GetBytes(character.ChestColor).Reverse()); ///Bracer color CharacterList.AddRange(BitConverter.GetBytes(character.BracerColor).Reverse()); ///Glove color CharacterList.AddRange(BitConverter.GetBytes(character.GlovesColor).Reverse()); ///Leg color CharacterList.AddRange(BitConverter.GetBytes(character.LegsColor).Reverse()); ///Boot color CharacterList.AddRange(BitConverter.GetBytes(character.BootsColor).Reverse()); ///Helm color CharacterList.AddRange(BitConverter.GetBytes(character.HelmColor).Reverse()); ///Robe color CharacterList.AddRange(BitConverter.GetBytes(character.RobeColor).Reverse()); Logger.Info($"Processed {character.CharName}"); } ///Character list is complete ///Handles packing message into outgoing packet RdpCommOut.PackMessage(MySession, CharacterList, MessageOpcodeTypes.ShortReliableMessage, GameOpcode.CharacterSelect); }
//Method to create new character when new character opcode is received private static void ProcessCreateChar(Session MySession, List <byte> myPacket) { //Create NewCharacter object Character charCreation = new Character(); //Log that a new character creation packet was received Logger.Info("Received Character Creation Packet"); //Get length of characters name expected in packet int nameLength = myPacket[3] << 24 | myPacket[2] << 16 | myPacket[1] << 8 | myPacket[0]; //Remove nameLength from packet myPacket.RemoveRange(0, 4); //var for actual character name byte[] characterNameArray = new byte[nameLength]; //Copy the actual character name to above variable myPacket.CopyTo(0, characterNameArray, 0, nameLength); //Remove charactername from packet myPacket.RemoveRange(0, nameLength); //Make charactername readable charCreation.CharName = Encoding.Default.GetString(characterNameArray); //Before processing a full character creation check if the characters name already exists in the DB. //Later this will need to include a character/world combination if additional servers are spun up. if (charCreation.CharName == SQLOperations.CheckName(charCreation.CharName)) { myPacket.Clear(); //List and assignment to hold game op code in bytes to send out List <byte> NameTaken = new List <byte>(); NameTaken.AddRange(BitConverter.GetBytes(GameOpcode.NameTaken)); //Log character name taken and send out RDP message to pop up that name is taken. Console.WriteLine("Character Name Already Taken"); RdpCommOut.PackMessage(MySession, MessageOpcodeTypes.ShortReliableMessage, GameOpcode.NameTaken); } //If name not found continue to actually create character else { //Get starting level charCreation.Level = Utility_Funcs.Untechnique(myPacket); //Divide startLevel by 2 because client doubles it //Get single byte attributes charCreation.Race = Utility_Funcs.Untechnique(myPacket); charCreation.StartingClass = Utility_Funcs.Untechnique(myPacket); charCreation.Gender = Utility_Funcs.Untechnique(myPacket); charCreation.HairColor = Utility_Funcs.Untechnique(myPacket); charCreation.HairLength = Utility_Funcs.Untechnique(myPacket); charCreation.HairStyle = Utility_Funcs.Untechnique(myPacket); charCreation.FaceOption = Utility_Funcs.Untechnique(myPacket); charCreation.HumTypeNum = Utility_Funcs.Untechnique(myPacket); //Get player attributes from packet and remove bytes after reading into variable charCreation.AddStrength = myPacket[3] << 24 | myPacket[2] << 16 | myPacket[1] << 8 | myPacket[0]; charCreation.AddStamina = myPacket[7] << 24 | myPacket[6] << 16 | myPacket[5] << 8 | myPacket[4]; charCreation.AddAgility = myPacket[11] << 24 | myPacket[10] << 16 | myPacket[9] << 8 | myPacket[8]; charCreation.AddDexterity = myPacket[15] << 24 | myPacket[14] << 16 | myPacket[13] << 8 | myPacket[12]; charCreation.AddWisdom = myPacket[19] << 24 | myPacket[18] << 16 | myPacket[17] << 8 | myPacket[16]; charCreation.AddIntelligence = myPacket[23] << 24 | myPacket[22] << 16 | myPacket[21] << 8 | myPacket[20]; charCreation.AddCharisma = myPacket[27] << 24 | myPacket[26] << 16 | myPacket[25] << 8 | myPacket[24]; myPacket.RemoveRange(0, 28); //Call SQL method for character creation SQLOperations.CreateCharacter(MySession, charCreation); } }
public static void ProcessMemoryDump(Session MySession) { //Let's get remaining character data before preparing it for transport //Hotkeys SQLOperations.GetPlayerHotkeys(MySession); //Quests, skip for now //Weaponhotbars SQLOperations.GetPlayerWeaponHotbar(MySession); //Auctions go here, skip for now //Spells SQLOperations.GetPlayerSpells(MySession); MySession.MyDumpData.AddRange(MySession.MyCharacter.PullCharacter()); MySession.MyDumpData.Add((byte)(MySession.MyCharacter.MyHotkeys.Count() * 2)); //cycle over all our hotkeys and append them foreach (Hotkey MyHotkey in MySession.MyCharacter.MyHotkeys) { MySession.MyDumpData.AddRange(MyHotkey.PullHotkey()); } //Unknown at this time 4 byte null MySession.MyDumpData.AddRange(BitConverter.GetBytes(0)); //Unknown at this time 4 byte null MySession.MyDumpData.AddRange(BitConverter.GetBytes(0)); //Quest Count MySession.MyDumpData.AddRange(BitConverter.GetBytes(MySession.MyCharacter.MyQuests.Count())); //Iterate over quest data and append (Should be 0 for now...) foreach (Quest MyQuest in MySession.MyCharacter.MyQuests) { MySession.MyDumpData.AddRange(MyQuest.PullQuest()); } //Get Inventory Item count MySession.MyDumpData.Add((byte)(MySession.MyCharacter.InventoryItems.Count() * 2)); MySession.MyDumpData.AddRange(BitConverter.GetBytes(MySession.MyCharacter.InventoryItems.Count())); foreach (Item MyItem in MySession.MyCharacter.InventoryItems) { MySession.MyDumpData.AddRange(MyItem.PullItem()); } foreach (WeaponHotbar MyWeaponHotbar in MySession.MyCharacter.WeaponHotbars) { MySession.MyDumpData.AddRange(MyWeaponHotbar.PullWeaponHotbar()); } //Get Bank Item count MySession.MyDumpData.Add((byte)(MySession.MyCharacter.BankItems.Count() * 2)); MySession.MyDumpData.AddRange(BitConverter.GetBytes(MySession.MyCharacter.BankItems.Count())); foreach (Item MyItem in MySession.MyCharacter.BankItems) { MySession.MyDumpData.AddRange(MyItem.PullItem()); } // end of bank? or could be something else for memory dump MySession.MyDumpData.Add((byte)0); //Buying auctions MySession.MyDumpData.Add((byte)(MySession.MyCharacter.MyBuyingAuctions.Count())); foreach (Auction MyAuction in MySession.MyCharacter.MyBuyingAuctions) { MySession.MyDumpData.AddRange(MyAuction.PullAuction()); } //Selling auctions MySession.MyDumpData.Add((byte)(MySession.MyCharacter.MySellingAuctions.Count())); foreach (Auction MyAuction in MySession.MyCharacter.MySellingAuctions) { MySession.MyDumpData.AddRange(MyAuction.PullAuction()); } //Spell count and Spells MySession.MyDumpData.AddRange(Utility_Funcs.Technique(MySession.MyCharacter.MySpells.Count())); foreach (Spell MySpell in MySession.MyCharacter.MySpells) { MySession.MyDumpData.AddRange(MySpell.PullSpell()); //Indicates end of spell? MySession.MyDumpData.Add((byte)0); } MySession.MyDumpData.AddRange(new byte[] { 0x55, 0x55, 0x0d, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x0f, 0xae, 0x98, 0x4c, 0x00, 0x55, 0x55, 0x0d, 0x41, 0xe6, 0x01, 0x96, 0x01, 0x78, 0x96, 0x01, 0x00, 0x00, 0x00, 0xde, 0x02, 0xde, 0x02, 0x00, 0xfa, 0x01, 0x00, 0x00, 0x00, 0xe8, 0x07, 0x00, 0x5a, 0x00, 0x00, 0x04, 0x00, 0x0c, 0x4f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x02, 0xde, 0x02, 0x00, 0xfa, 0x01, 0x00, 0x00, 0x00 }); MySession.Dumpstarted = true; //Get our timestamp opcode in queue RdpCommOut.PackMessage(MySession, DNP3Creation.CreateDNP3TimeStamp(), MessageOpcodeTypes.ShortReliableMessage, GameOpcode.Time); List <byte> ThisChunk; //Gather our dump data if (MySession.MyDumpData.Count() > 500) { ThisChunk = MySession.MyDumpData.GetRange(0, 500); MySession.MyDumpData.RemoveRange(0, 500); //Set this to true to send packet to client MySession.ClientFirstConnect = true; ///Handles packing message into outgoing packet RdpCommOut.PackMessage(MySession, ThisChunk, MessageOpcodeTypes.MultiShortReliableMessage, GameOpcode.MemoryDump); } //Dump data is smaller then 500 bytes else { ThisChunk = MySession.MyDumpData.GetRange(0, MySession.MyDumpData.Count()); MySession.MyDumpData.Clear(); //Set this to true to send packet to client MySession.ClientFirstConnect = true; //Appears dump is short, end it here MySession.Dumpstarted = false; ///Handles packing message into outgoing packet RdpCommOut.PackMessage(MySession, ThisChunk, MessageOpcodeTypes.ShortReliableMessage, GameOpcode.MemoryDump); } }
static public void ReadConfig() { try { Logger.Info("Connecting to config file"); ///Connects to our config file var appSettings = ConfigurationManager.AppSettings; ///Checks for our "ServerCount" config option string result = appSettings["Servercount"] ?? "Not Found"; ///Check if results were found if (result == "Not Found") { Logger.Err("Config file not found, is it present?"); } else { try { Logger.Info($"Acquiring Server Config, total of {result} config's"); ///Convert our result to an int int ServerCount = Int32.Parse(result); ///Add Server count to our preformed packet ServerList.AddRange(Utility_Funcs.Technique(ServerCount)); ///Cycle through servers in Config List for (int i = 0; i < ServerCount; i++) { ///Gets Server Name and Name Length string ServerName = appSettings[$"Server{i}"]; int ServerNameLength = ServerName.Length; ///Add Server name length ServerList.AddRange(BitConverter.GetBytes(ServerNameLength)); ///Add Server Name in unicode ServerList.AddRange(unicode.GetBytes(ServerName)); byte ServerRecommended = (byte)(Convert.ToUInt32(appSettings[$"ServerRecommended{i}"])); ///Add Server Recommendation ServerList.Add(ServerRecommended); ushort ServerEndPointID = Convert.ToUInt16(appSettings[$"ServerEndPointID{i}"]); ///Add Server End Point ServerList.AddRange(BitConverter.GetBytes(ServerEndPointID)); ushort ServerPort = Convert.ToUInt16(appSettings[$"ServerPort{i}"]); ///Add Server Port ServerList.AddRange(BitConverter.GetBytes(ServerPort)); IPAddress ServerIP = IPAddress.Parse(appSettings[$"ServerIP{i}"]); ///Add Server IP and reverse bytes ServerList.AddRange((ServerIP.GetAddressBytes()).Reverse()); byte ServerLanguage = (byte)(Convert.ToUInt32(appSettings[$"ServerLanguage{i}"])); ServerList.Add(ServerLanguage); Logger.Info($"Acquired Server #{i + 1}"); } Logger.Info("Done..."); } catch (FormatException) { Logger.Err($"Unable to parse '{result}'"); } } } catch (ConfigurationErrorsException) { Logger.Err("Error reading app settings"); } }