public void HandlePacket(GameClient client, GSPacketIn packet) { if (client.Player == null) return; uint X = packet.ReadInt(); uint Y = packet.ReadInt(); ushort id =(ushort) packet.ReadShort(); ushort obj=(ushort) packet.ReadShort(); GameObject target = client.Player.TargetObject; if (target == null) { client.Out.SendMessage(LanguageMgr.GetTranslation(client.Account.Language, "PlayerPickUpRequestHandler.HandlePacket.Target"), eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } if (target.ObjectState != GameObject.eObjectState.Active) { client.Out.SendMessage(LanguageMgr.GetTranslation(client.Account.Language, "PlayerPickUpRequestHandler.HandlePacket.InvalidTarget"), eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } client.Player.PickupObject(target, false); }
public void HandlePacket(GameClient client, GSPacketIn packet) { if (client == null || client.Player == null) return; if (client.Player.ObjectState != GameObject.eObjectState.Active) return; ushort sessionId = packet.ReadShort(); // session ID if (client.SessionID != sessionId) { // GameServer.BanAccount(client, 120, "Hack sessionId", string.Format("Wrong sessionId:0x{0} in 0xBA packet (SessionID:{1})", sessionId, client.SessionID)); return; // client hack } ushort head = packet.ReadShort(); client.Player.Heading = (ushort)(head & 0xFFF); packet.Skip(1); // unknown int flags = packet.ReadByte(); // client.Player.PetInView = ((flags & 0x04) != 0); // TODO client.Player.GroundTargetInView = ((flags & 0x08) != 0); client.Player.TargetInView = ((flags & 0x10) != 0); byte[] con = packet.ToArray(); if (!client.Player.IsAlive) { con[9] = 5; // set dead state } else if (client.Player.Steed != null && client.Player.Steed.ObjectState == GameObject.eObjectState.Active) { client.Player.Heading = client.Player.Steed.Heading; con[9] = 6; // Set ride state con[7] = (byte)(client.Player.Steed.RiderSlot(client.Player)); // there rider slot this player con[2] = (byte)(client.Player.Steed.ObjectID >> 8); //heading = steed ID con[3] = (byte)(client.Player.Steed.ObjectID & 0xFF); } con[5] &= 0xC0; //11 00 00 00 = 0x80(Torch) + 0x40(Unknown), all other in view check's not need send anyone if (client.Player.IsWireframe) { con[5] |= 0x01; } //stealth is set here if (client.Player.IsStealthed) { con[5] |= 0x02; } con[8] = (byte)((con[8] & 0x80) | client.Player.HealthPercent); GSUDPPacketOut outpak = new GSUDPPacketOut(client.Out.GetPacketCode(eServerPackets.PlayerHeading)); //Now copy the whole content of the packet outpak.Write(con, 0, /*con.Length*/10); outpak.WritePacketLength(); GSUDPPacketOut outpak190 = null; // byte[] outp = outpak.GetBuffer(); // outpak = null; foreach(GamePlayer player in client.Player.GetPlayersInRadius(WorldMgr.VISIBILITY_DISTANCE)) { if(player != null && player != client.Player) { if (player.Client.Version >= GameClient.eClientVersion.Version190) { if (outpak190 == null) { outpak190 = new GSUDPPacketOut(client.Out.GetPacketCode(eServerPackets.PlayerHeading)); byte[] con190 = (byte[]) con.Clone(); //Now copy the whole content of the packet outpak190.Write(con190, 0, /*con190.Lenght*/10); outpak190.WriteByte(client.Player.ManaPercent); outpak190.WriteByte(client.Player.EndurancePercent); outpak190.WritePacketLength(); // byte[] outp190 = outpak190.GetBuffer(); // outpak190 = null;// ? } player.Out.SendUDPRaw(outpak190); } else player.Out.SendUDPRaw(outpak); } } }
//static int lastZ=int.MinValue; public void HandlePacket(GameClient client, GSPacketIn packet) { //Tiv: in very rare cases client send 0xA9 packet before sending S<=C 0xE8 player world initialize if ((client.Player.ObjectState != GameObject.eObjectState.Active) || (client.ClientState != GameClient.eClientState.Playing)) return; int environmentTick = Environment.TickCount; int packetVersion; if (client.Version > GameClient.eClientVersion.Version171) { packetVersion = 172; } else { packetVersion = 168; } int oldSpeed = client.Player.CurrentSpeed; //read the state of the player packet.Skip(2); //PID ushort data = packet.ReadShort(); int speed = (data & 0x1FF); // if(!GameServer.ServerRules.IsAllowedDebugMode(client) // && (speed > client.Player.MaxSpeed + SPEED_TOL)) if ((data & 0x200) != 0) speed = -speed; if (client.Player.IsMezzed || client.Player.IsStunned) { // Nidel: updating client.Player.CurrentSpeed instead of speed client.Player.CurrentSpeed = 0; } else { client.Player.CurrentSpeed = (short)speed; } client.Player.IsStrafing = ((data & 0xe000) != 0); int realZ = packet.ReadShort(); ushort xOffsetInZone = packet.ReadShort(); ushort yOffsetInZone = packet.ReadShort(); ushort currentZoneID; if (packetVersion == 168) { currentZoneID = (ushort)packet.ReadByte(); packet.Skip(1); //0x00 padding for zoneID } else { currentZoneID = packet.ReadShort(); } //Dinberg - Instance considerations. //Now this gets complicated, so listen up! We have told the client a lie when it comes to the zoneID. //As a result, every movement update, they are sending a lie back to us. Two liars could get confusing! //BUT, the lie we sent has a truth to it - the geometry and layout of the zone. As a result, the zones //x and y offsets will still actually be relevant to our current zone. And for the clones to have been //created, there must have been a real zone to begin with, of id == instanceZone.SkinID. //So, although our client is lying to us, and thinks its in another zone, that zone happens to coincide //exactly with the zone we are instancing - and so all the positions still ring true. //Philosophically speaking, its like looking in a mirror and saying 'Am I a reflected, or reflector?' //What it boils down to has no bearing whatsoever on the result of anything, so long as someone sitting //outside of the unvierse knows not to listen to whether you say which you are, and knows the truth to the //answer. Then, he need only know what you are doing ;) Zone newZone = WorldMgr.GetZone(currentZoneID); if (newZone == null) { if(client.Player==null) return; if(!client.Player.TempProperties.getProperty("isbeingbanned",false)) { if (log.IsErrorEnabled) log.Error(client.Player.Name + "'s position in unknown zone! => " + currentZoneID); GamePlayer player=client.Player; player.TempProperties.setProperty("isbeingbanned", true); player.MoveToBind(); } return; // TODO: what should we do? player lost in space } // move to bind if player fell through the floor if (realZ == 0) { client.Player.MoveTo( (ushort)client.Player.BindRegion, client.Player.BindXpos, client.Player.BindYpos, (ushort)client.Player.BindZpos, (ushort)client.Player.BindHeading ); return; } int realX = newZone.XOffset + xOffsetInZone; int realY = newZone.YOffset + yOffsetInZone; bool zoneChange = newZone != client.Player.LastPositionUpdateZone; if (zoneChange) { //If the region changes -> make sure we don't take any falling damage if (client.Player.LastPositionUpdateZone != null && newZone.ZoneRegion.ID != client.Player.LastPositionUpdateZone.ZoneRegion.ID) client.Player.MaxLastZ = int.MinValue; // Update water level and diving flag for the new zone client.Out.SendPlayerPositionAndObjectID(); zoneChange = true; /* * "You have entered Burial Tomb." * "Burial Tomb" * "Current area is adjusted for one level 1 player." * "Current area has a 50% instance bonus." */ string description = newZone.Description; string screenDescription = description; var translation = client.GetTranslation(newZone) as DBLanguageZone; if (translation != null) { if (!Util.IsEmpty(translation.Description)) description = translation.Description; if (!Util.IsEmpty(translation.ScreenDescription)) screenDescription = translation.ScreenDescription; } client.Out.SendMessage(LanguageMgr.GetTranslation(client.Account.Language, "PlayerPositionUpdateHandler.Entered", description), eChatType.CT_System, eChatLoc.CL_SystemWindow); client.Out.SendMessage(screenDescription, eChatType.CT_ScreenCenterSmaller, eChatLoc.CL_SystemWindow); client.Player.LastPositionUpdateZone = newZone; } int coordsPerSec = 0; int jumpDetect = 0; int timediff = Environment.TickCount - client.Player.LastPositionUpdateTick; int distance = 0; if (timediff > 0) { distance = client.Player.LastPositionUpdatePoint.GetDistanceTo(new Point3D(realX, realY, realZ)); coordsPerSec = distance * 1000 / timediff; if (distance < 100 && client.Player.LastPositionUpdatePoint.Z > 0) { jumpDetect = realZ - client.Player.LastPositionUpdatePoint.Z; } } #region DEBUG #if OUTPUT_DEBUG_INFO if (client.Player.LastPositionUpdatePoint.X != 0 && client.Player.LastPositionUpdatePoint.Y != 0) { log.Debug(client.Player.Name + ": distance = " + distance + ", speed = " + oldSpeed + ", coords/sec=" + coordsPerSec); } if (jumpDetect > 0) { log.Debug(client.Player.Name + ": jumpdetect = " + jumpDetect); } #endif #endregion DEBUG client.Player.LastPositionUpdateTick = Environment.TickCount; client.Player.LastPositionUpdatePoint.X = realX; client.Player.LastPositionUpdatePoint.Y = realY; client.Player.LastPositionUpdatePoint.Z = realZ; int tolerance = ServerProperties.Properties.CPS_TOLERANCE; if (client.Player.Steed != null && client.Player.Steed.MaxSpeed > 0) { tolerance += client.Player.Steed.MaxSpeed; } else if (client.Player.MaxSpeed > 0) { tolerance += client.Player.MaxSpeed; } if (client.Player.IsJumping) { coordsPerSec = 0; jumpDetect = 0; client.Player.IsJumping = false; } if (client.Player.IsAllowedToFly == false && (coordsPerSec > tolerance || jumpDetect > ServerProperties.Properties.JUMP_TOLERANCE)) { bool isHackDetected = true; if (coordsPerSec > tolerance) { // check to see if CPS time tolerance is exceeded int lastCPSTick = client.Player.TempProperties.getProperty<int>(LASTCPSTICK, 0); if (environmentTick - lastCPSTick > ServerProperties.Properties.CPS_TIME_TOLERANCE) { isHackDetected = false; } } if (isHackDetected) { StringBuilder builder = new StringBuilder(); builder.Append("MOVEHACK_DETECT"); builder.Append(": CharName="); builder.Append(client.Player.Name); builder.Append(" Account="); builder.Append(client.Account.Name); builder.Append(" IP="); builder.Append(client.TcpEndpointAddress); builder.Append(" CPS:="); builder.Append(coordsPerSec); builder.Append(" JT="); builder.Append(jumpDetect); ChatUtil.SendDebugMessage(client, builder.ToString()); if (client.Account.PrivLevel == 1) { GameServer.Instance.LogCheatAction(builder.ToString()); if (ServerProperties.Properties.ENABLE_MOVEDETECT) { if (ServerProperties.Properties.BAN_HACKERS && false) // banning disabled until this technique is proven accurate { DBBannedAccount b = new DBBannedAccount(); b.Author = "SERVER"; b.Ip = client.TcpEndpointAddress; b.Account = client.Account.Name; b.DateBan = DateTime.Now; b.Type = "B"; b.Reason = string.Format("Autoban MOVEHACK:(CPS:{0}, JT:{1}) on player:{2}", coordsPerSec, jumpDetect, client.Player.Name); GameServer.Database.AddObject(b); GameServer.Database.SaveObject(b); string message = ""; message = "You have been auto kicked and banned due to movement hack detection!"; for (int i = 0; i < 8; i++) { client.Out.SendMessage(message, eChatType.CT_Help, eChatLoc.CL_SystemWindow); client.Out.SendMessage(message, eChatType.CT_Help, eChatLoc.CL_ChatWindow); } client.Out.SendPlayerQuit(true); client.Player.SaveIntoDatabase(); client.Player.Quit(true); } else { string message = ""; message = "You have been auto kicked due to movement hack detection!"; for (int i = 0; i < 8; i++) { client.Out.SendMessage(message, eChatType.CT_Help, eChatLoc.CL_SystemWindow); client.Out.SendMessage(message, eChatType.CT_Help, eChatLoc.CL_ChatWindow); } client.Out.SendPlayerQuit(true); client.Player.SaveIntoDatabase(); client.Player.Quit(true); } client.Disconnect(); return; } } } client.Player.TempProperties.setProperty(LASTCPSTICK, environmentTick); } ushort headingflag = packet.ReadShort(); client.Player.Heading = (ushort)(headingflag & 0xFFF); ushort flyingflag = packet.ReadShort(); byte flags = (byte)packet.ReadByte(); if (client.Player.X != realX || client.Player.Y != realY) { client.Player.TempProperties.setProperty(LASTMOVEMENTTICK, client.Player.CurrentRegion.Time); } client.Player.X = realX; client.Player.Y = realY; client.Player.Z = realZ; if (zoneChange) { // update client zone information for waterlevel and diving client.Out.SendPlayerPositionAndObjectID(); } // used to predict current position, should be before // any calculation (like fall damage) client.Player.MovementStartTick = Environment.TickCount; // Begin ---------- New Area System ----------- if (client.Player.CurrentRegion.Time > client.Player.AreaUpdateTick) // check if update is needed { var oldAreas = client.Player.CurrentAreas; // Because we may be in an instance we need to do the area check from the current region // rather than relying on the zone which is in the skinned region. - Tolakram var newAreas = client.Player.CurrentRegion.GetAreasOfZone(newZone, client.Player); // Check for left areas if (oldAreas != null) { foreach (IArea area in oldAreas) { if (!newAreas.Contains(area)) { area.OnPlayerLeave(client.Player); } } } // Check for entered areas foreach (IArea area in newAreas) { if (oldAreas == null || !oldAreas.Contains(area)) { area.OnPlayerEnter(client.Player); } } // set current areas to new one... client.Player.CurrentAreas = newAreas; client.Player.AreaUpdateTick = client.Player.CurrentRegion.Time + 2000; // update every 2 seconds } // End ---------- New Area System ----------- client.Player.TargetInView = ((flags & 0x10) != 0); client.Player.GroundTargetInView = ((flags & 0x08) != 0); client.Player.IsTorchLighted = ((flags & 0x80) != 0); //7 6 5 4 3 2 1 0 //15 14 13 12 11 10 9 8 // 1 1 const string SHLASTUPDATETICK = "SHPLAYERPOSITION_LASTUPDATETICK"; const string SHLASTFLY = "SHLASTFLY_STRING"; const string SHLASTSTATUS = "SHLASTSTATUS_STRING"; int SHlastTick = client.Player.TempProperties.getProperty<int>(SHLASTUPDATETICK); int SHlastFly = client.Player.TempProperties.getProperty<int>(SHLASTFLY); int SHlastStatus = client.Player.TempProperties.getProperty<int>(SHLASTSTATUS); int SHcount = client.Player.TempProperties.getProperty<int>(SHSPEEDCOUNTER); int status = (data & 0x1FF ^ data) >> 8; int fly = (flyingflag & 0x1FF ^ flyingflag) >> 8; if (client.Player.IsJumping) { SHcount = 0; } if (SHlastTick != 0 && SHlastTick != environmentTick) { if (((SHlastStatus == status || (status & 0x8) == 0)) && ((fly & 0x80) != 0x80) && (SHlastFly == fly || (SHlastFly & 0x10) == (fly & 0x10) || !((((SHlastFly & 0x10) == 0x10) && ((fly & 0x10) == 0x0) && (flyingflag & 0x7FF) > 0)))) { if ((environmentTick - SHlastTick) < 400) { SHcount++; if (SHcount > 1 && client.Account.PrivLevel > 1) { //Apo: ?? no idea how to name the first parameter for language translation: 1: ??, 2: {detected} ?, 3: {count} ? client.Out.SendMessage(string.Format("SH: ({0}) detected: {1}, count {2}", 500 / (environmentTick - SHlastTick), environmentTick - SHlastTick, SHcount), eChatType.CT_Staff, eChatLoc.CL_SystemWindow); } if (SHcount % 5 == 0) { StringBuilder builder = new StringBuilder(); builder.Append("TEST_SH_DETECT["); builder.Append(SHcount); builder.Append("] ("); builder.Append(environmentTick - SHlastTick); builder.Append("): CharName="); builder.Append(client.Player.Name); builder.Append(" Account="); builder.Append(client.Account.Name); builder.Append(" IP="); builder.Append(client.TcpEndpointAddress); GameServer.Instance.LogCheatAction(builder.ToString()); if (client.Account.PrivLevel > 1) { client.Out.SendMessage("SH: Logging SH cheat.", eChatType.CT_Damaged, eChatLoc.CL_SystemWindow); if (SHcount >= ServerProperties.Properties.SPEEDHACK_TOLERANCE) client.Out.SendMessage("SH: Player would have been banned!", eChatType.CT_Damaged, eChatLoc.CL_SystemWindow); } if ((client.Account.PrivLevel == 1) && SHcount >= ServerProperties.Properties.SPEEDHACK_TOLERANCE) { if (ServerProperties.Properties.BAN_HACKERS) { DBBannedAccount b = new DBBannedAccount(); b.Author = "SERVER"; b.Ip = client.TcpEndpointAddress; b.Account = client.Account.Name; b.DateBan = DateTime.Now; b.Type = "B"; b.Reason = string.Format("Autoban SH:({0},{1}) on player:{2}", SHcount, environmentTick - SHlastTick, client.Player.Name); GameServer.Database.AddObject(b); GameServer.Database.SaveObject(b); string message = ""; message = "You have been auto kicked and banned for speed hacking!"; for (int i = 0; i < 8; i++) { client.Out.SendMessage(message, eChatType.CT_Help, eChatLoc.CL_SystemWindow); client.Out.SendMessage(message, eChatType.CT_Help, eChatLoc.CL_ChatWindow); } client.Out.SendPlayerQuit(true); client.Player.SaveIntoDatabase(); client.Player.Quit(true); } else { string message = ""; message = "You have been auto kicked for speed hacking!"; for (int i = 0; i < 8; i++) { client.Out.SendMessage(message, eChatType.CT_Help, eChatLoc.CL_SystemWindow); client.Out.SendMessage(message, eChatType.CT_Help, eChatLoc.CL_ChatWindow); } client.Out.SendPlayerQuit(true); client.Player.SaveIntoDatabase(); client.Player.Quit(true); } client.Disconnect(); return; } } } else { SHcount = 0; } SHlastTick = environmentTick; } } else { SHlastTick = environmentTick; } int state = ((data >> 10) & 7); client.Player.IsClimbing = (state == 7); client.Player.IsSwimming = (state == 1); if (state == 3 && client.Player.TempProperties.getProperty<bool>(GamePlayer.DEBUG_MODE_PROPERTY, false) == false && client.Player.IsAllowedToFly == false) //debugFly on, but player not do /debug on (hack) { StringBuilder builder = new StringBuilder(); builder.Append("HACK_FLY"); builder.Append(": CharName="); builder.Append(client.Player.Name); builder.Append(" Account="); builder.Append(client.Account.Name); builder.Append(" IP="); builder.Append(client.TcpEndpointAddress); GameServer.Instance.LogCheatAction(builder.ToString()); { if (ServerProperties.Properties.BAN_HACKERS) { DBBannedAccount b = new DBBannedAccount(); b.Author = "SERVER"; b.Ip = client.TcpEndpointAddress; b.Account = client.Account.Name; b.DateBan = DateTime.Now; b.Type = "B"; b.Reason = string.Format("Autoban flying hack: on player:{0}", client.Player.Name); GameServer.Database.AddObject(b); GameServer.Database.SaveObject(b); } string message = ""; message = "Client Hack Detected!"; for (int i = 0; i < 6; i++) { client.Out.SendMessage(message, eChatType.CT_System, eChatLoc.CL_SystemWindow); client.Out.SendMessage(message, eChatType.CT_System, eChatLoc.CL_ChatWindow); } client.Out.SendPlayerQuit(true); client.Disconnect(); return; } } SHlastFly = fly; SHlastStatus = status; client.Player.TempProperties.setProperty(SHLASTUPDATETICK, SHlastTick); client.Player.TempProperties.setProperty(SHLASTFLY, SHlastFly); client.Player.TempProperties.setProperty(SHLASTSTATUS, SHlastStatus); client.Player.TempProperties.setProperty(SHSPEEDCOUNTER, SHcount); lock (client.Player.LastUniqueLocations) { GameLocation[] locations = client.Player.LastUniqueLocations; GameLocation loc = locations[0]; if (loc.X != realX || loc.Y != realY || loc.Z != realZ || loc.RegionID != client.Player.CurrentRegionID) { loc = locations[locations.Length - 1]; Array.Copy(locations, 0, locations, 1, locations.Length - 1); locations[0] = loc; loc.X = realX; loc.Y = realY; loc.Z = realZ; loc.Heading = client.Player.Heading; loc.RegionID = client.Player.CurrentRegionID; } } //**************// //FALLING DAMAGE// //**************// if (GameServer.ServerRules.CanTakeFallDamage(client.Player) && client.Player.IsSwimming == false) { int maxLastZ = client.Player.MaxLastZ; /* Are we on the ground? */ if ((flyingflag >> 15) != 0) { int safeFallLevel = client.Player.GetAbilityLevel(Abilities.SafeFall); int fallSpeed = (flyingflag & 0xFFF) - 100 * safeFallLevel; // 0x7FF fall speed and 0x800 bit = fall speed overcaped int fallMinSpeed = 400; int fallDivide = 6; if (client.Version >= GameClient.eClientVersion.Version188) { fallMinSpeed = 500; fallDivide = 15; } int fallPercent = Math.Min(99, (fallSpeed - (fallMinSpeed + 1)) / fallDivide); if (fallSpeed > fallMinSpeed) { client.Out.SendMessage(LanguageMgr.GetTranslation(client.Account.Language, "PlayerPositionUpdateHandler.FallingDamage"), eChatType.CT_Damaged, eChatLoc.CL_SystemWindow); client.Player.CalcFallDamage(fallPercent); } client.Player.MaxLastZ = client.Player.Z; } else { // always set Z if on the ground if (flyingflag == 0) client.Player.MaxLastZ = client.Player.Z; // set Z if in air and higher than old Z else if (maxLastZ < client.Player.Z) client.Player.MaxLastZ = client.Player.Z; } } //**************// byte[] con168 = packet.ToArray(); con168[0] = (byte)(client.SessionID >> 8); con168[1] = (byte)(client.SessionID & 0xff); //Riding is set here! if (client.Player.Steed != null && client.Player.Steed.ObjectState == GameObject.eObjectState.Active) { client.Player.Heading = client.Player.Steed.Heading; con168[2] = 0x18; // Set ride flag 00011000 con168[3] = 0; // player speed = 0 while ride con168[12] = (byte)(client.Player.Steed.ObjectID >> 8); //heading = steed ID con168[13] = (byte)(client.Player.Steed.ObjectID & 0xFF); con168[14] = (byte)0; con168[15] = (byte)(client.Player.Steed.RiderSlot(client.Player)); // there rider slot this player } else if (!client.Player.IsAlive) { con168[2] &= 0xE3; //11100011 con168[2] |= 0x14; //Set dead flag 00010100 } //diving is set here con168[16] &= 0xFB; //11 11 10 11 if ((con168[16] & 0x02) != 0x00) { client.Player.IsDiving = true; con168[16] |= 0x04; } else client.Player.IsDiving = false; con168[16] &= 0xFC; //11 11 11 00 cleared Wireframe & Stealth bits if (client.Player.IsWireframe) { con168[16] |= 0x01; } //stealth is set here if (client.Player.IsStealthed) { con168[16] |= 0x02; } con168[17] = (byte)((con168[17] & 0x80) | client.Player.HealthPercent); // zone ID has changed in 1.72, fix bytes 11 and 12 byte[] con172 = (byte[])con168.Clone(); if (packetVersion == 168) { // client sent v168 pos update packet, fix 172 version con172[10] = 0; con172[11] = con168[10]; } else { // client sent v172 pos update packet, fix 168 version con168[10] = con172[11]; con168[11] = 0; } GSUDPPacketOut outpak168 = new GSUDPPacketOut(client.Out.GetPacketCode(eServerPackets.PlayerPosition)); //Now copy the whole content of the packet outpak168.Write(con168, 0, 18/*con168.Length*/); outpak168.WritePacketLength(); GSUDPPacketOut outpak172 = new GSUDPPacketOut(client.Out.GetPacketCode(eServerPackets.PlayerPosition)); //Now copy the whole content of the packet outpak172.Write(con172, 0, 18/*con172.Length*/); outpak172.WritePacketLength(); // byte[] pak168 = outpak168.GetBuffer(); // byte[] pak172 = outpak172.GetBuffer(); // outpak168 = null; // outpak172 = null; GSUDPPacketOut outpak190 = null; GSUDPPacketOut outpak1112 = new GSUDPPacketOut(client.Out.GetPacketCode(eServerPackets.PlayerPosition)); outpak1112.Write(con172, 0, 18/*con172.Length*/); outpak1112.WriteByte(client.Player.ManaPercent); outpak1112.WriteByte(client.Player.EndurancePercent); outpak1112.WriteByte((byte)(client.Player.RPFlag ? 1 : 0)); outpak1112.WriteByte(0); //outpak1112.WriteByte((con168.Length == 22) ? con168[21] : (byte)0); outpak1112.WritePacketLength(); foreach (GamePlayer player in client.Player.GetPlayersInRadius(WorldMgr.VISIBILITY_DISTANCE)) { if (player == null) continue; //No position updates for ourselves if (player == client.Player) { // Update Player Cache (Client sending Packet is admitting he's already having it) player.Client.GameObjectUpdateArray[new Tuple<ushort, ushort>(client.Player.CurrentRegionID, (ushort)client.Player.ObjectID)] = GameTimer.GetTickCount(); continue; } //no position updates in different houses if ((client.Player.InHouse || player.InHouse) && player.CurrentHouse != client.Player.CurrentHouse) continue; if (client.Player.MinotaurRelic != null) { MinotaurRelic relic = client.Player.MinotaurRelic; if (!relic.Playerlist.Contains(player) && player != client.Player) { relic.Playerlist.Add(player); player.Out.SendMinotaurRelicWindow(client.Player, client.Player.MinotaurRelic.Effect, true); } } if (!client.Player.IsStealthed || player.CanDetect(client.Player)) { // Update Player Cache player.Client.GameObjectUpdateArray[new Tuple<ushort, ushort>(client.Player.CurrentRegionID, (ushort)client.Player.ObjectID)] = GameTimer.GetTickCount(); //forward the position packet like normal! if (player.Client.Version >= GameClient.eClientVersion.Version1112) { player.Out.SendUDPRaw(outpak1112); } else if (player.Client.Version >= GameClient.eClientVersion.Version190) { if (outpak190 == null) { outpak190 = new GSUDPPacketOut(client.Out.GetPacketCode(eServerPackets.PlayerPosition)); outpak190.Write(con172, 0, 18/*con172.Length*/); outpak190.WriteByte(client.Player.ManaPercent); outpak190.WriteByte(client.Player.EndurancePercent); outpak190.FillString(client.Player.CharacterClass.Name, 32); // roleplay flag, if == 1, show name (RP) with gray color if (client.Player.RPFlag) outpak190.WriteByte(1); else outpak190.WriteByte(0); outpak190.WriteByte((con168.Length == 54) ? con168[53] : (byte) 0); // send last byte for 190+ packets outpak190.WritePacketLength(); } player.Out.SendUDPRaw(outpak190); } else if (player.Client.Version >= GameClient.eClientVersion.Version172) player.Out.SendUDPRaw(outpak172); else player.Out.SendUDPRaw(outpak168); } else player.Out.SendObjectDelete(client.Player); //remove the stealthed player from view } if (client.Player.CharacterClass.ID == (int)eCharacterClass.Warlock) { //Send Chamber effect client.Player.Out.SendWarlockChamberEffect(client.Player); } //handle closing of windows //trade window if (client.Player.TradeWindow != null) { if (client.Player.TradeWindow.Partner != null) { if (!client.Player.IsWithinRadius(client.Player.TradeWindow.Partner, WorldMgr.GIVE_ITEM_DISTANCE)) client.Player.TradeWindow.CloseTrade(); } } }
public void HandlePacket(GameClient client, GSPacketIn packet) { ushort id = packet.ReadShort(); ushort toSlot = packet.ReadShort(); ushort fromSlot = packet.ReadShort(); ushort itemCount= packet.ReadShort(); //log.Debug("MoveItem, id=" + id + " toSlot=" + toSlot + " fromSlot=" + fromSlot + " itemCount=" + itemCount); //ChatUtil.SendDebugMessage(client, "MoveItem, id=" + id.ToString() + " toSlot=" + toSlot.ToString() + " fromSlot=" + fromSlot.ToString() + " itemCount=" + itemCount.ToString()); //If our slot is > 1000 it is (objectID+1000) of target if(toSlot>1000) { ushort objectID = (ushort)(toSlot-1000); GameObject obj = WorldMgr.GetObjectByIDFromRegion(client.Player.CurrentRegionID,objectID); if(obj==null || obj.ObjectState!=GameObject.eObjectState.Active) { client.Out.SendInventorySlotsUpdate(new int[] {fromSlot}); client.Out.SendMessage("Invalid trade target. ("+objectID+")", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } GamePlayer tradeTarget = obj as GamePlayer; // If our target is another player we set the tradetarget // trade permissions are done in GamePlayer if (tradeTarget != null) { if(tradeTarget.Client.ClientState != GameClient.eClientState.Playing) { client.Out.SendInventorySlotsUpdate(new int[] {fromSlot}); client.Out.SendMessage("Can't trade with inactive players.", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } if(tradeTarget == client.Player) { client.Out.SendInventorySlotsUpdate(new int[] {fromSlot}); client.Out.SendMessage("You can't trade with yourself, silly!",eChatType.CT_System,eChatLoc.CL_SystemWindow); return; } if(!GameServer.ServerRules.IsAllowedToTrade(client.Player, tradeTarget, false)) { client.Out.SendInventorySlotsUpdate(new int[] {fromSlot}); return; } } // Is the item we want to move in our backpack? // we also allow drag'n drop from equipped to blacksmith if ((fromSlot >= (ushort)eInventorySlot.FirstBackpack && fromSlot <= (ushort)eInventorySlot.LastBackpack) || (obj is Blacksmith && fromSlot>=(ushort) eInventorySlot.MinEquipable && fromSlot<=(ushort) eInventorySlot.MaxEquipable)) { if (!obj.IsWithinRadius(client.Player, WorldMgr.GIVE_ITEM_DISTANCE)) { if (obj is GamePlayer) client.Out.SendMessage(LanguageMgr.GetTranslation(client, "PlayerMoveItemRequestHandler.TooFarAway", client.Player.GetName((GamePlayer)obj)), eChatType.CT_System, eChatLoc.CL_SystemWindow); else client.Out.SendMessage(LanguageMgr.GetTranslation(client, "PlayerMoveItemRequestHandler.TooFarAway", obj.GetName(0, false)), eChatType.CT_System, eChatLoc.CL_SystemWindow); //client.Out.SendMessage("You are too far away to give anything to " + obj.GetName(0, false) + ".", eChatType.CT_System, eChatLoc.CL_SystemWindow); client.Out.SendInventorySlotsUpdate(new int[] { fromSlot }); return; } InventoryItem item = client.Player.Inventory.GetItem((eInventorySlot)fromSlot); if (item == null) { client.Out.SendInventorySlotsUpdate(new int[] { fromSlot }); client.Out.SendMessage("Invalid item (slot# " + fromSlot + ").", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } if (obj is GameNPC == false || item.Count == 1) client.Player.Notify(GamePlayerEvent.GiveItem, client.Player, new GiveItemEventArgs(client.Player, obj, item)); //If the item has been removed by the event handlers, return; //item = client.Player.Inventory.GetItem((eInventorySlot)fromSlot); if (item == null || item.OwnerID == null) { client.Out.SendInventorySlotsUpdate(new int[] { fromSlot }); return; } if(client.Account.PrivLevel == (uint)ePrivLevel.Player && tradeTarget != null && tradeTarget.Client.Account.PrivLevel != (uint)ePrivLevel.Player) { if(!item.IsDropable && !(obj is GameNPC && (obj is Blacksmith || obj is Recharger || (obj as GameNPC).CanTradeAnyItem))) { client.Out.SendInventorySlotsUpdate(new int[] { fromSlot }); client.Out.SendMessage("You can not remove this item!", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } } if(tradeTarget != null) { tradeTarget.ReceiveTradeItem(client.Player, item); client.Out.SendInventorySlotsUpdate(new int[] { fromSlot }); return; } if (obj.ReceiveItem(client.Player, item)) { client.Out.SendInventorySlotsUpdate(new int[] { fromSlot }); return; } client.Out.SendInventorySlotsUpdate(new int[] { fromSlot }); return; } //Is the "item" we want to move money? For Version 1.78+ if(client.Version >= GameClient.eClientVersion.Version178 && fromSlot >= (int)eInventorySlot.Mithril178 && fromSlot <= (int)eInventorySlot.Copper178) { fromSlot -= eInventorySlot.Mithril178 - eInventorySlot.Mithril; } //Is the "item" we want to move money? if(fromSlot>=(ushort)eInventorySlot.Mithril && fromSlot<=(ushort)eInventorySlot.Copper) { int[] money=new int[5]; money[fromSlot-(ushort)eInventorySlot.Mithril]=itemCount; long flatmoney = Money.GetMoney(money[0],money[1],money[2],money[3],money[4]); if(client.Version >= GameClient.eClientVersion.Version178) // add it back for proper slot update... fromSlot += eInventorySlot.Mithril178 - eInventorySlot.Mithril; if (!obj.IsWithinRadius(client.Player, WorldMgr.GIVE_ITEM_DISTANCE)) { if (obj is GamePlayer) client.Out.SendMessage(LanguageMgr.GetTranslation(client, "PlayerMoveItemRequestHandler.TooFarAway", client.Player.GetName((GamePlayer)obj)), eChatType.CT_System, eChatLoc.CL_SystemWindow); else client.Out.SendMessage(LanguageMgr.GetTranslation(client, "PlayerMoveItemRequestHandler.TooFarAway", obj.GetName(0, false)), eChatType.CT_System, eChatLoc.CL_SystemWindow); //client.Out.SendMessage("You are too far away to give anything to " + obj.GetName(0, false) + ".", eChatType.CT_System, eChatLoc.CL_SystemWindow); client.Out.SendInventorySlotsUpdate(new int[] {fromSlot}); return; } if(flatmoney > client.Player.GetCurrentMoney()) { client.Out.SendInventorySlotsUpdate(new int[] {fromSlot}); return; } client.Player.Notify(GamePlayerEvent.GiveMoney, client.Player, new GiveMoneyEventArgs(client.Player, obj, flatmoney)); if(tradeTarget!=null) { tradeTarget.ReceiveTradeMoney(client.Player, flatmoney); client.Out.SendInventorySlotsUpdate(new int[] {fromSlot}); return; } if(obj.ReceiveMoney(client.Player, flatmoney)) { client.Out.SendInventorySlotsUpdate(new int[] {fromSlot}); return; } client.Out.SendInventorySlotsUpdate(new int[] {fromSlot}); return; } client.Out.SendInventoryItemsUpdate(null); return; } // House Vaults and GameConsignmentMerchant Merchants deliver the same slot numbers if (fromSlot >= (ushort)eInventorySlot.HousingInventory_First && fromSlot <= (ushort)eInventorySlot.HousingInventory_Last) { GameVault ghv = client.Player.ActiveVault; GameConsignmentMerchant cm = client.Player.ActiveConMerchant; if (cm != null) // we have an active GameConsignmentMerchant Merchant { if (ghv != null) //this should never happen { client.Out.SendInventoryItemsUpdate(null); return; } fromSlot += 1350; } } if (toSlot >= (ushort)eInventorySlot.HousingInventory_First && toSlot <= (ushort)eInventorySlot.HousingInventory_Last) { GameVault ghv = client.Player.ActiveVault; GameConsignmentMerchant cm = client.Player.ActiveConMerchant; if (cm != null) // we have an active GameConsignmentMerchant Merchant { if (ghv != null) //this should never happen { client.Out.SendInventoryItemsUpdate(null); return; } toSlot += 1350; } } bool fromHousing = (fromSlot >= (ushort)eInventorySlot.HousingInventory_First && fromSlot <= (ushort)eInventorySlot.HousingInventory_Last); bool toHousing = (toSlot >= (ushort)eInventorySlot.HousingInventory_First && toSlot <= (ushort)eInventorySlot.HousingInventory_Last); // Move an item from, to or inside a vault. if (fromHousing || toHousing) { GameVault houseVault = client.Player.ActiveVault; if (fromSlot >= (ushort)eInventorySlot.FirstBackpack && fromSlot <= (ushort)eInventorySlot.LastBackpack) { InventoryItem item = client.Player.Inventory.GetItem((eInventorySlot)fromSlot); if (!item.IsTradable) { client.Out.SendMessage("You can not put this Item into a House Vault!", eChatType.CT_System, eChatLoc.CL_SystemWindow); client.Out.SendInventoryItemsUpdate(null); return; } } if (houseVault == null) { client.Out.SendMessage("You are not actively viewing a vault!", eChatType.CT_System, eChatLoc.CL_SystemWindow); client.Out.SendInventoryItemsUpdate(null); return; } if (toHousing && !houseVault.CanAddItems(client.Player)) { client.Out.SendMessage("You don't have permission to add items!", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } if (fromHousing && !houseVault.CanRemoveItems(client.Player)) { client.Out.SendMessage("You don't have permission to remove items!", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } houseVault.MoveItem(client.Player, (eInventorySlot)fromSlot, (eInventorySlot)toSlot); return; } // Move an item from, to or inside a GameConsignmentMerchant Merchant. if ((fromSlot >= (ushort)eInventorySlot.Consignment_First && fromSlot <= (ushort)eInventorySlot.Consignment_Last) || (toSlot >= (ushort)eInventorySlot.Consignment_First && toSlot <= (ushort)eInventorySlot.Consignment_Last)) { GameConsignmentMerchant con = client.Player.ActiveConMerchant; if (con == null) { client.Out.SendMessage("You are not actively interacting with a GameConsignmentMerchant Merchant!", eChatType.CT_System, eChatLoc.CL_SystemWindow); client.Out.SendInventoryItemsUpdate(null); return; } if (fromSlot >= (ushort)eInventorySlot.FirstBackpack && fromSlot <= (ushort)eInventorySlot.LastBackpack) { InventoryItem item = client.Player.Inventory.GetItem((eInventorySlot)fromSlot); if (!item.IsTradable) { client.Out.SendMessage("You can not put this Item into a GameConsignmentMerchant Merchant!", eChatType.CT_System, eChatLoc.CL_SystemWindow); client.Out.SendInventoryItemsUpdate(null); return; } } if (toSlot >= (ushort)eInventorySlot.Consignment_First && toSlot <= (ushort)eInventorySlot.Consignment_Last) { if (!con.CanMove(client.Player)) { client.Out.SendMessage("You don't have permission to add or move Items!", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } } con.MoveItem(client.Player, client.Player.Inventory, (eInventorySlot)fromSlot, (eInventorySlot)toSlot); return; } if (fromSlot >= (ushort)eInventorySlot.MarketExplorerFirst && toSlot >= (ushort)eInventorySlot.FirstBackpack && toSlot <= (ushort)eInventorySlot.LastBackpack && client.Player.ActiveVault == null) // a possible buy from a market explorer { if (client.Player.TargetObject == null) return; if (!(client.Player.TargetObject is MarketExplorer)) return; var list = client.Player.TempProperties.getProperty<List<InventoryItem>>(PlayerMarketSearchRequestHandler.EXPLORER_LIST, null); if (list == null) return; var me = client.Player.TargetObject as MarketExplorer; int itemnr = fromSlot - (int)eInventorySlot.MarketExplorerFirst; InventoryItem item = list[itemnr]; me.BuyItem(item, client.Player); } //Do we want to move an item from inventory/vault/quiver into inventory/vault/quiver? if (((fromSlot>=(ushort)eInventorySlot.Ground && fromSlot<=(ushort)eInventorySlot.LastBackpack) || (fromSlot >=(ushort)eInventorySlot.FirstVault && fromSlot<=(ushort)eInventorySlot.LastVault) || (fromSlot >=(ushort)eInventorySlot.FirstBagHorse && fromSlot <=(ushort)eInventorySlot.LastBagHorse)) &&((toSlot >=(ushort)eInventorySlot.Ground && toSlot<=(ushort)eInventorySlot.LastBackpack) || (toSlot >=(ushort)eInventorySlot.FirstVault && toSlot<=(ushort)eInventorySlot.LastVault) || (toSlot >=(ushort)eInventorySlot.HousingInventory_First && toSlot<=(ushort)eInventorySlot.HousingInventory_Last) || (toSlot >=(ushort)eInventorySlot.FirstBagHorse && toSlot <=(ushort)eInventorySlot.LastBagHorse))) { //We want to drop the item if (toSlot==(ushort)eInventorySlot.Ground) { InventoryItem item = client.Player.Inventory.GetItem((eInventorySlot)fromSlot); if (item == null) { client.Out.SendInventorySlotsUpdate(new int[] {fromSlot}); client.Out.SendMessage("Invalid item (slot# "+fromSlot+").",eChatType.CT_System,eChatLoc.CL_SystemWindow); return; } if (fromSlot<(ushort)eInventorySlot.FirstBackpack) { client.Out.SendInventorySlotsUpdate(new int[] {fromSlot}); return; } if(!item.IsDropable) { client.Out.SendInventorySlotsUpdate(new int[] {fromSlot}); client.Out.SendMessage("You can not drop this item!",eChatType.CT_System,eChatLoc.CL_SystemWindow); return; } if (client.Player.DropItem((eInventorySlot)fromSlot)) { client.Out.SendMessage("You drop " + item.GetName(0, false) + " on the ground!",eChatType.CT_System,eChatLoc.CL_SystemWindow); return; } client.Out.SendInventoryItemsUpdate(null); return; } //We want to move the item in inventory client.Player.Inventory.MoveItem((eInventorySlot)fromSlot, (eInventorySlot)toSlot, itemCount); return; } if (((fromSlot>=(ushort)eInventorySlot.Ground && fromSlot<=(ushort)eInventorySlot.LastBackpack) || (fromSlot>=(ushort)eInventorySlot.FirstVault && fromSlot<=(ushort)eInventorySlot.LastVault) || (fromSlot >=(ushort)eInventorySlot.FirstBagHorse && fromSlot <=(ushort)eInventorySlot.LastBagHorse)) && ((toSlot==(ushort)eInventorySlot.PlayerPaperDoll || toSlot==(ushort)eInventorySlot.NewPlayerPaperDoll) || (toSlot>=(ushort)eInventorySlot.Ground && toSlot<=(ushort)eInventorySlot.LastBackpack) || (toSlot>=(ushort)eInventorySlot.FirstVault && toSlot<=(ushort)eInventorySlot.LastVault) || (toSlot >=(ushort)eInventorySlot.FirstBagHorse && toSlot <=(ushort)eInventorySlot.LastBagHorse))) { InventoryItem item = client.Player.Inventory.GetItem((eInventorySlot)fromSlot); if(item==null) return; toSlot=0; if(item.Item_Type >= (int)eInventorySlot.MinEquipable && item.Item_Type <= (int)eInventorySlot.MaxEquipable) toSlot = (ushort)item.Item_Type; if (toSlot==0) { client.Out.SendInventorySlotsUpdate(new int[] {fromSlot}); return; } if( toSlot == (int)eInventorySlot.LeftBracer || toSlot == (int)eInventorySlot.RightBracer) { if(client.Player.Inventory.GetItem(eInventorySlot.LeftBracer) == null) toSlot = (int)eInventorySlot.LeftBracer; else toSlot = (int)eInventorySlot.RightBracer; } if( toSlot == (int)eInventorySlot.LeftRing || toSlot == (int)eInventorySlot.RightRing) { if(client.Player.Inventory.GetItem(eInventorySlot.LeftRing) == null) toSlot = (int)eInventorySlot.LeftRing; else toSlot = (int)eInventorySlot.RightRing; } client.Player.Inventory.MoveItem((eInventorySlot)fromSlot,(eInventorySlot)toSlot, itemCount); return; } client.Out.SendInventoryItemsUpdate(null); }
public void HandlePacket(GameClient client, GSPacketIn packet) { if (client.Player == null) return; ushort id = packet.ReadShort(); ushort toClientSlot = packet.ReadShort(); ushort fromClientSlot = packet.ReadShort(); ushort itemCount = packet.ReadShort(); //ChatUtil.SendDebugMessage(client, "GM: MoveItem; id=" + id.ToString() + " client fromSlot=" + fromClientSlot.ToString() + " client toSlot=" + toClientSlot.ToString() + " itemCount=" + itemCount.ToString()); // If our toSlot is > 1000 then target is a game object (not a window) with an ObjectID of toSlot - 1000 if (toClientSlot > 1000) { ushort objectID = (ushort)(toClientSlot - 1000); GameObject obj = WorldMgr.GetObjectByIDFromRegion(client.Player.CurrentRegionID, objectID); if (obj == null || obj.ObjectState != GameObject.eObjectState.Active) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); client.Out.SendMessage("Invalid trade target. (" + objectID + ")", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } GamePlayer tradeTarget = obj as GamePlayer; // If our target is another player we set the tradetarget // trade permissions are done in GamePlayer if (tradeTarget != null) { if (tradeTarget.Client.ClientState != GameClient.eClientState.Playing) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); client.Out.SendMessage("Can't trade with inactive players.", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } if (tradeTarget == client.Player) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); client.Out.SendMessage("You can't trade with yourself, silly!", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } if (!GameServer.ServerRules.IsAllowedToTrade(client.Player, tradeTarget, false)) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } } // Is the item we want to move in our backpack? // we also allow drag'n drop from equipped to blacksmith if ((fromClientSlot >= (ushort)eInventorySlot.FirstBackpack && fromClientSlot <= (ushort)eInventorySlot.LastBackpack) || (obj is Blacksmith && fromClientSlot >= (ushort)eInventorySlot.MinEquipable && fromClientSlot <= (ushort)eInventorySlot.MaxEquipable)) { if (!obj.IsWithinRadius(client.Player, WorldMgr.GIVE_ITEM_DISTANCE)) { // show too far away message if (obj is GamePlayer) { client.Out.SendMessage(LanguageMgr.GetTranslation(client.Account.Language, "PlayerMoveItemRequestHandler.TooFarAway", client.Player.GetName((GamePlayer)obj)), eChatType.CT_System, eChatLoc.CL_SystemWindow); } else { client.Out.SendMessage(LanguageMgr.GetTranslation(client.Account.Language, "PlayerMoveItemRequestHandler.TooFarAway", obj.GetName(0, false)), eChatType.CT_System, eChatLoc.CL_SystemWindow); } client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } InventoryItem item = client.Player.Inventory.GetItem((eInventorySlot)fromClientSlot); if (item == null) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); client.Out.SendMessage("Null item (client slot# " + fromClientSlot + ").", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } if (obj is GameNPC == false || item.Count == 1) { // see if any event handlers will handle this move client.Player.Notify(GamePlayerEvent.GiveItem, client.Player, new GiveItemEventArgs(client.Player, obj, item)); } //If the item has been removed by the event handlers, return; if (item == null || item.OwnerID == null) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } // if a player to a GM and item is not dropable then don't allow trade???? This seems wrong. if (client.Account.PrivLevel == (uint)ePrivLevel.Player && tradeTarget != null && tradeTarget.Client.Account.PrivLevel != (uint)ePrivLevel.Player) { if (!item.IsDropable && !(obj is GameNPC && (obj is Blacksmith || obj is Recharger || (obj as GameNPC).CanTradeAnyItem))) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); client.Out.SendMessage("You can not remove this item!", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } } if (tradeTarget != null) { // This is a player trade, let trade code handle tradeTarget.ReceiveTradeItem(client.Player, item); client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } if (obj.ReceiveItem(client.Player, item)) { // this object was expecting an item and handled it client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } //Is the "item" we want to move money? For Version 1.78+ if (client.Version >= GameClient.eClientVersion.Version178 && fromClientSlot >= (int)eInventorySlot.Mithril178 && fromClientSlot <= (int)eInventorySlot.Copper178) { fromClientSlot -= eInventorySlot.Mithril178 - eInventorySlot.Mithril; } //Is the "item" we want to move money? if (fromClientSlot >= (ushort)eInventorySlot.Mithril && fromClientSlot <= (ushort)eInventorySlot.Copper) { int[] money = new int[5]; money[fromClientSlot - (ushort)eInventorySlot.Mithril] = itemCount; long flatMoney = Money.GetMoney(money[0], money[1], money[2], money[3], money[4]); if (client.Version >= GameClient.eClientVersion.Version178) // add it back for proper slot update... { fromClientSlot += eInventorySlot.Mithril178 - eInventorySlot.Mithril; } if (!obj.IsWithinRadius(client.Player, WorldMgr.GIVE_ITEM_DISTANCE)) { // show too far away message if (obj is GamePlayer) { client.Out.SendMessage(LanguageMgr.GetTranslation(client.Account.Language, "PlayerMoveItemRequestHandler.TooFarAway", client.Player.GetName((GamePlayer)obj)), eChatType.CT_System, eChatLoc.CL_SystemWindow); } else { client.Out.SendMessage(LanguageMgr.GetTranslation(client.Account.Language, "PlayerMoveItemRequestHandler.TooFarAway", obj.GetName(0, false)), eChatType.CT_System, eChatLoc.CL_SystemWindow); } client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } if (flatMoney > client.Player.GetCurrentMoney()) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } client.Player.Notify(GamePlayerEvent.GiveMoney, client.Player, new GiveMoneyEventArgs(client.Player, obj, flatMoney)); if (tradeTarget != null) { tradeTarget.ReceiveTradeMoney(client.Player, flatMoney); client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } if (obj.ReceiveMoney(client.Player, flatMoney)) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } client.Out.SendInventoryItemsUpdate(null); return; } // We did not drop an item on a game object, which means we should have valid from and to slots // since we are moving an item from one window to another. // First check for an active InventoryObject if (client.Player.ActiveInventoryObject != null && client.Player.ActiveInventoryObject.MoveItem(client.Player, fromClientSlot, toClientSlot)) { //ChatUtil.SendDebugMessage(client, "ActiveInventoryObject handled move"); return; } //Do we want to move an item from immediate inventory to immediate inventory or drop on the ground if (((fromClientSlot >= (ushort)eInventorySlot.Ground && fromClientSlot <= (ushort)eInventorySlot.LastBackpack) || (fromClientSlot >= (ushort)eInventorySlot.FirstVault && fromClientSlot <= (ushort)eInventorySlot.LastVault) || (fromClientSlot >= (ushort)eInventorySlot.FirstBagHorse && fromClientSlot <= (ushort)eInventorySlot.LastBagHorse)) && ((toClientSlot >= (ushort)eInventorySlot.Ground && toClientSlot <= (ushort)eInventorySlot.LastBackpack) || (toClientSlot >= (ushort)eInventorySlot.FirstVault && toClientSlot <= (ushort)eInventorySlot.LastVault) || (toClientSlot >= (ushort)eInventorySlot.FirstBagHorse && toClientSlot <= (ushort)eInventorySlot.LastBagHorse))) { //We want to drop the item if (toClientSlot == (ushort)eInventorySlot.Ground) { InventoryItem item = client.Player.Inventory.GetItem((eInventorySlot)fromClientSlot); if (item == null) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); client.Out.SendMessage("Invalid item (slot# " + fromClientSlot + ").", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } if (fromClientSlot < (ushort)eInventorySlot.FirstBackpack) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } if (!item.IsDropable) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); client.Out.SendMessage("You can not drop this item!", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } if (client.Player.DropItem((eInventorySlot)fromClientSlot)) { client.Out.SendMessage("You drop " + item.GetName(0, false) + " on the ground!", eChatType.CT_System, eChatLoc.CL_SystemWindow); return; } client.Out.SendInventoryItemsUpdate(null); return; } client.Player.Inventory.MoveItem((eInventorySlot)fromClientSlot, (eInventorySlot)toClientSlot, itemCount); //ChatUtil.SendDebugMessage(client, "Player.Inventory handled move"); return; } if (((fromClientSlot >= (ushort)eInventorySlot.Ground && fromClientSlot <= (ushort)eInventorySlot.LastBackpack) || (fromClientSlot >= (ushort)eInventorySlot.FirstVault && fromClientSlot <= (ushort)eInventorySlot.LastVault) || (fromClientSlot >= (ushort)eInventorySlot.FirstBagHorse && fromClientSlot <= (ushort)eInventorySlot.LastBagHorse)) && ((toClientSlot == (ushort)eInventorySlot.PlayerPaperDoll || toClientSlot == (ushort)eInventorySlot.NewPlayerPaperDoll) || (toClientSlot >= (ushort)eInventorySlot.Ground && toClientSlot <= (ushort)eInventorySlot.LastBackpack) || (toClientSlot >= (ushort)eInventorySlot.FirstVault && toClientSlot <= (ushort)eInventorySlot.LastVault) || (toClientSlot >= (ushort)eInventorySlot.FirstBagHorse && toClientSlot <= (ushort)eInventorySlot.LastBagHorse))) { InventoryItem item = client.Player.Inventory.GetItem((eInventorySlot)fromClientSlot); if (item == null) return; toClientSlot = 0; if (item.Item_Type >= (int)eInventorySlot.MinEquipable && item.Item_Type <= (int)eInventorySlot.MaxEquipable) toClientSlot = (ushort)item.Item_Type; if (toClientSlot == 0) { client.Out.SendInventorySlotsUpdate(new int[] { fromClientSlot }); return; } if (toClientSlot == (int)eInventorySlot.LeftBracer || toClientSlot == (int)eInventorySlot.RightBracer) { if (client.Player.Inventory.GetItem(eInventorySlot.LeftBracer) == null) toClientSlot = (int)eInventorySlot.LeftBracer; else toClientSlot = (int)eInventorySlot.RightBracer; } if (toClientSlot == (int)eInventorySlot.LeftRing || toClientSlot == (int)eInventorySlot.RightRing) { if (client.Player.Inventory.GetItem(eInventorySlot.LeftRing) == null) toClientSlot = (int)eInventorySlot.LeftRing; else toClientSlot = (int)eInventorySlot.RightRing; } client.Player.Inventory.MoveItem((eInventorySlot)fromClientSlot, (eInventorySlot)toClientSlot, itemCount); //ChatUtil.SendDebugMessage(client, "Player.Inventory handled move (2)"); return; } client.Out.SendInventoryItemsUpdate(null); }