leorbmello
Member-
Posts
11 -
Joined
-
Last visited
Reputation
0 NeutralPersonal Information
-
Location
New York
Recent Profile Visitors
The recent visitors block is disabled and is not being shown to other users.
-
leorbmello started following Konichu
-
Just wondering if there is any benefit to "winding" down these maps if they had no activity for a while? I.e. turning off generators for those specific maps and trying to get it to unload from memory? Is that instead too risky to do once it's already loaded and thus better to just hold the high memory usage? I recognize that maintenance sorts these issues out but figured I'd ask. Thanks! I believe I may have been wrong about what I really meant ... I do not remove what has already been created from monsters on the map, I just stop processing the respawn until a player returns to that map, avoiding creating entities that will not be active (this does not delete or remove the monsters that have already been created) previously) As for the loading of the map, I do not see any problem for now in working in this way, since important maps are always loaded. What stops being processed is just the generator. It was a simple idea, it may not be good in the long run, for now it is working well and without complaints, it is just a way to reduce the use of Generator'sThread. It would be pretty bad if i had to be reprocessing and recreate every entity on the map every time it's been out of use. Also, i guess for dynamaps, you could create something like: ConcurrentDictionary> Objects main index as MAP id and second entityID and role object... (stupid idea) this way you could use a single title base to hold some event maps as arena, you would not need to recreate the entire floor...
-
I don't know if it will help you, but... Like Spirited said, it saved me alot of memory usage. I made the server load basically all maps patch (GameMap.dat) and load just a few maps... most important ones, like city maps and quest maps. the most used ones, they're just a few, so.... The others if they would be used, the system loads the map when someone teleport there (yeah, you may feel like laggy when teleport to it for first time, but take no more than 2 or 3 seconds to the server load the map) and if the map has monsters or generator, the generator start just when the map has been activated.
-
For sure i will!
-
Well, i found the problem! Tq changed the StringLenght offset to Ushort, so, if i would write a string to a packet the structure now is: (Ushort) Value.Lenght (String) Value
-
It seems the packet is using the ProtoBuf... this makes a lot of sense, tested using protobuf at the MsgTaskDialog and i got some things working now, but not with the UserInfo one yet.... i checked out for 0x404 and from what i've seen it is 0x408, sometimes 0x410... so i don't really got yet.
-
Hey let's populate this forum hehe I'm using the Client version 6907 and i used the MACOS Client like Spirited's tutorial and i got the packet structures for two basic things that i'm having problens at this version. 1st: The CMsgUserInfo does not spawn the character name, but everything else is set correctly. 2nd: The CMsgTaskDialog (Npc Dialogs) i can spawn the picture and the box but not the texts. So, i'm trying to understand the whole thing, i got many things working already Here we have the Packet base Constructors but the things seems to have changed a lot from the older clients, or am i missing something basic. int __ZN12CMsgUserInfoC2Ev() { CNetMsg::CNetMsg(); *rdi = 0x101a66a50; CNetStringPacker::CNetStringPacker(); CNetMsg::Init(); *(rdi + 0x408) = rdi + 0x8; rax = CNetStringPacker::SetBuf(rdi + 0x410, rdi + 0xa1); return rax; } int __ZN12CMsgUserInfo6CreateEPcj(int * arg0, unsigned int arg1) { rbx = arg0; rcx = CNetMsg::Create(arg0, arg1); rax = 0x0; if (rcx != 0x0) { rax = (*(int16_t *)(rbx + 0xa) & 0xffff) == 0x8ad ? 0x1 : 0x0; } return rax; } This is the CMsgUserInfo::Process (when client receives the packet from server and build the Hero), it was very interesting to see how the things go this far, i've ben for hours to check it and i'm getting excited to learn more about those things, so here we go. The code is big so i removed the end of it because there is a limit of the characteres to post this. I could identify nearly all offsets, and they match for sure with the tests. The name is missing, but, i would like to understand why the name is being set at first, the offsets are set into the order from id to the final of the packet, so.... Is the name before the Character informations, or am i wrong? Other thing is, the strings 3 strings (name, last name and mate) are set to max lenght (32), i could see it at the beggining of the method... The 0xa1(161) is the base packet lenght and the other 0x8ad(2221) is the packet id. Obs.: Also i would love to discuss this at discord with someone, i really want to learn more about this.
-
Aww thanks, good point, i've checked the wiki and also got nearly all offsets of the packet, just missing the name one. Gonna try the disassembler, thanks!
-
I've already setup the msg action correctly and some other packets, but i have a problem with showing the character name on the client with the character info, seems i'm missing the offset... i've tested the trial and error like building and rebuilding, offset by offset... but i didn't make it... i could spawn all character main informations correctly, but not the name... from what i've seen, the ShowName offset has been removed, is that correct? By the way, this will be a opensource project... i just want to setup the basics.
-
The problem was just the ActionType... i was sending it wrong, i can login already, i just have to work on the positions now.
-
Hi guys, I might need a help on understanding what am i missing here. * Client version 6907 I already know that the packet id's have changed and already updated the packet id list. From what i can see, the client is ready to display the character at the screen and so on... but i get stuck at Initializing after sending the CofirmLocation information, it seems i'm missing something at the login sequence to get there. Well, this is the message action handler: public void MsgActionHandler(ClientSocket pClient, byte[] buffer) { MsgAction pInfo = new MsgAction(buffer); switch (pInfo.Action) { case MsgActionType.ConfirmLocation: { // send location to the client pClient.Send(new MsgAction(pClient.Character.Identity, 10160, pClient.Character.PosX, pClient.Character.PosY, MsgActionType.ConfirmLocation)); // load character inventory and equipments before spawn to others. // pClient.Character.LoadInventory(); // pClient.Character.LoadEquipment(); // // execute the entermap (load screen and etc) pClient.Character.EnterMap(); break; } /*case MsgActionType.ConfirmHotkeys: { //pClient.Send(pInfo); break; } case MsgActionType.ConfirmFriends: { // pClient.Send(pInfo); break; } case MsgActionType.ConfirmProficiencies: { // pClient.Character.SendCharacterProfs(); // pClient.Send(pInfo); break; } case MsgActionType.ConfirmSpells: { // pClient.Character.SendCharacterMagics(); // pClient.Send(pInfo); break; } case MsgActionType.ConfirmGuild: { // pClient.Send(pInfo); break; } case MsgActionType.ConfirmLogin: { // pClient.Send(pInfo); break; } case MsgActionType.ChangeFlyMapPortal: { if(!WorldManager.Portals.ContainsKey(pClient.Character.MapIdentity)) { Program.WriteLine("Invalid mapportal at : " + pClient.Character.MapIdentity + "(" + pClient.Character.PosX + ", " + pClient.Character.PosY + ")"); pClient.Character.FlyMap(1002, 430, 380); return; } PortalInfo pPortal = null; foreach (PortalInfo pPortalInfo in WorldManager.Portals[pClient.Character.MapIdentity].Values) if (pPortalInfo.PosX == pInfo.LeftData0 && pPortalInfo.PosY == pInfo.RightData0) { pPortal = pPortalInfo; break; } if (pPortal == null) { Program.WriteLine("Invalid passway at : " + pClient.Character.MapIdentity + "(" + pClient.Character.PosX + ", " + pClient.Character.PosY + ")"); pClient.Character.FlyMap(1002, 430, 380); return; } pClient.Character.FlyMap(pPortal.TargetMap, pPortal.TargetPosX, pPortal.TargetPosY); break; } case MsgActionType.PlayerJump: { pClient.Character.MovePos(MoveModeType.Jump, 0, pInfo.LeftData0, pInfo.RightData0, pInfo); break; }*/ case MsgActionType.ChangePKMode: { pInfo.Info.dwParam3 = pInfo.Info.dwParam; pClient.Send(pInfo); break; } default: { Program.WriteLine(String.Format("Missing MsgAction Handler: {0}[{1}]", pInfo.Action, (int)pInfo.Action)); Report(buffer); pClient.Send(pInfo); break; } } } When i send the ConfirmLocation, the client replies the ChangePK packet... From what i could check, the new versions are using the ProtoBuffer to build some packets, so i tested using this structure for the MsgAction: [ProtoContract] public class MsgActionInfo { [ProtoMember(1, IsRequired = true)] public uint Identity; [ProtoMember(2)] public uint Target; [ProtoMember(3)] public uint dwParam; [ProtoMember(4)] public int dwParam2; [ProtoMember(5)] public long dwParam3; [ProtoMember(6)] public bool SucDone; [ProtoMember(7)] public uint TargetPositionX; [ProtoMember(8)] public uint TargetPositionY; [ProtoMember(9, IsRequired = true)] public uint Timestamp; [ProtoMember(10)] public int TargetNpcIdentity; [ProtoMember(11)] public uint CheatLogData1; [ProtoMember(12, IsRequired = true)] public ushort Type; [ProtoMember(13, IsRequired = true)] public ushort Facing; [ProtoMember(14, IsRequired = true)] public uint PositionX; [ProtoMember(15, IsRequired = true)] public uint PositionY; [ProtoMember(16)] public uint CheatLogData2; [ProtoMember(17)] public uint MapID; [ProtoMember(18)] public uint CheatLogData3; [ProtoMember(19)] public int ScheduleTime; [ProtoMember(20)] public int LinkIndex; [ProtoMember(21)] public uint CheatLogData4; [ProtoMember(22)] public int RemainTime; [ProtoMember(23)] public bool MountCharge; [ProtoMember(24)] public List<byte[]> Strings; } And i got stuck here: Is there something new to the ConfirmLocation, or is the packet structure wrong?