public void HandlePacket(GameClient client, GSPacketIn packet) { int flagSpeedData; int spellLevel; int spellLineIndex; if (client.Version >= GameClient.eClientVersion.Version1124) { client.Player.X = (int)packet.ReadFloatLowEndian(); client.Player.Y = (int)packet.ReadFloatLowEndian(); client.Player.Z = (int)packet.ReadFloatLowEndian(); client.Player.CurrentSpeed = (short)packet.ReadFloatLowEndian(); client.Player.Heading = packet.ReadShort(); flagSpeedData = packet.ReadShort(); // target visible ? 0xA000 : 0x0000 spellLevel = packet.ReadByte(); spellLineIndex = packet.ReadByte(); // two bytes at end, not sure what for } else { flagSpeedData = packet.ReadShort(); int heading = packet.ReadShort(); if (client.Version > GameClient.eClientVersion.Version171) { int xOffsetInZone = packet.ReadShort(); int yOffsetInZone = packet.ReadShort(); int currentZoneID = packet.ReadShort(); int realZ = packet.ReadShort(); Zone newZone = WorldMgr.GetZone((ushort)currentZoneID); if (newZone == null) { Log.Warn($"Unknown zone in UseSpellHandler: {currentZoneID} player: {client.Player.Name}"); } else { client.Player.X = newZone.XOffset + xOffsetInZone; client.Player.Y = newZone.YOffset + yOffsetInZone; client.Player.Z = realZ; client.Player.MovementStartTick = Environment.TickCount; } } spellLevel = packet.ReadByte(); spellLineIndex = packet.ReadByte(); client.Player.Heading = (ushort)(heading & 0xfff); } new UseSpellAction(client.Player, flagSpeedData, spellLevel, spellLineIndex).Start(1); }
public void HandlePacket(GameClient client, GSPacketIn packet) { client.Player.X = (int)packet.ReadFloatLowEndian(); client.Player.Y = (int)packet.ReadFloatLowEndian(); client.Player.Z = (int)packet.ReadFloatLowEndian(); client.Player.CurrentSpeed = (short)packet.ReadFloatLowEndian(); client.Player.Heading = packet.ReadShort(); ushort flags = packet.ReadShort(); // target visible ? 0xA000 : 0x0000 int slot = packet.ReadByte(); int type = packet.ReadByte(); new UseSlotAction1124(client.Player, flags, slot, type).Start(1); }
public void HandlePacket(GameClient client, GSPacketIn packet) { client.Player.X = (int)packet.ReadFloatLowEndian(); client.Player.Y = (int)packet.ReadFloatLowEndian(); client.Player.Z = (int)packet.ReadFloatLowEndian(); client.Player.CurrentSpeed = (short)packet.ReadFloatLowEndian(); client.Player.Heading = packet.ReadShort(); ushort flags = packet.ReadShort(); // target visible ? 0xA000 : 0x0000 int spellLevel = packet.ReadByte(); int spellLineIndex = packet.ReadByte(); // two bytes at end, not sure what for client.Player.MovementStartTick = Environment.TickCount; // need to investigate this new UseSpellAction(client.Player, flags, spellLevel, spellLineIndex).Start(1); }
public void HandlePacket(GameClient client, GSPacketIn packet) { client.Player.X = (int)packet.ReadFloatLowEndian(); client.Player.Y = (int)packet.ReadFloatLowEndian(); client.Player.Z = (int)packet.ReadFloatLowEndian(); client.Player.CurrentSpeed = (short)packet.ReadFloatLowEndian(); client.Player.Heading = packet.ReadShort(); ushort flags = packet.ReadShort(); // target visible ? 0xA000 : 0x0000 int index = packet.ReadByte(); int type = packet.ReadByte(); // two bytes at end, not sure what for new UseSkillAction1124(client.Player, flags, index, type).Start(1); }
public void HandlePacket(GameClient client, GSPacketIn packet) { if (client.Version >= GameClient.eClientVersion.Version1124) { client.Player.X = (int)packet.ReadFloatLowEndian(); client.Player.Y = (int)packet.ReadFloatLowEndian(); client.Player.Z = (int)packet.ReadFloatLowEndian(); client.Player.CurrentSpeed = (short)packet.ReadFloatLowEndian(); client.Player.Heading = packet.ReadShort(); } int flagSpeedData = packet.ReadShort(); int slot = packet.ReadByte(); int type = packet.ReadByte(); new UseSlotAction(client.Player, flagSpeedData, slot, type).Start(1); }
public void HandlePacket(GameClient client, GSPacketIn packet) { if (client.Version >= GameClient.eClientVersion.Version1124) { var x = packet.ReadFloatLowEndian(); var y = packet.ReadFloatLowEndian(); var z = packet.ReadFloatLowEndian(); client.Player.Position = new Vector3(x, y, z); client.Player.CurrentSpeed = (short)packet.ReadFloatLowEndian(); client.Player.Heading = packet.ReadShort(); } int flagSpeedData = packet.ReadShort(); int index = packet.ReadByte(); int type = packet.ReadByte(); new UseSkillAction(client.Player, flagSpeedData, index, type).Start(1); }
//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 oldSpeed = client.Player.CurrentSpeed; int newPlayerX = (int)packet.ReadFloatLowEndian(); int newPlayerY = (int)packet.ReadFloatLowEndian(); int newPlayerZ = (int)packet.ReadFloatLowEndian(); int newPlayerSpeed = (int)packet.ReadFloatLowEndian(); int newPlayerZSpeed = (int)packet.ReadFloatLowEndian(); ushort sessionID = packet.ReadShort(); ushort currentZoneID = packet.ReadShort(); ushort playerState = packet.ReadShort(); ushort fallingDMG = packet.ReadShort(); ushort newHeading = packet.ReadShort(); byte playerAction = (byte)packet.ReadByte(); packet.Skip(2); // unknown bytes x2 byte playerHealth = (byte)packet.ReadByte(); // two trailing bytes, no data //int speed = (newPlayerSpeed & 0x1FF); //Flags1 = (eFlags1)playerState; //Flags2 = (eFlags2)playerAction; if (client.Player.IsMezzed || client.Player.IsStunned) { // Nidel: updating client.Player.CurrentSpeed instead of speed client.Player.CurrentSpeed = 0; } else { client.Player.CurrentSpeed = (short)newPlayerSpeed; } /* * client.Player.IsStrafing = Flags1 == eFlags1.STRAFELEFT || Flags1 == eFlags1.STRAFERIGHT; * client.Player.IsDiving = Flags2 == eFlags2.DIVING ? true : false; * client.Player.IsSwimming = Flags1 == eFlags1.SWIMMING ? true : false; * if (client.Player.IsRiding) * Flags1 = eFlags1.RIDING; * client.Player.IsClimbing = Flags1 == eFlags1.CLIMBING ? true : false; * if (!client.Player.IsAlive) * Flags1 = eFlags1.DEAD;*/ client.Player.IsJumping = ((playerAction & 0x40) != 0); client.Player.IsStrafing = ((playerState & 0xe000) != 0); 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 (newPlayerZ == 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 = newPlayerX; //int realY = newPlayerY; //int realZ = newPlayerZ; 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(newPlayerX, newPlayerY, newPlayerZ)); coordsPerSec = distance * 1000 / timediff; if (distance < 100 && client.Player.LastPositionUpdatePoint.Z > 0) { jumpDetect = newPlayerZ - client.Player.LastPositionUpdatePoint.Z; } } client.Player.LastPositionUpdateTick = Environment.TickCount; client.Player.LastPositionUpdatePoint.X = newPlayerX; client.Player.LastPositionUpdatePoint.Y = newPlayerY; client.Player.LastPositionUpdatePoint.Z = newPlayerZ; 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 && (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); } //client.Player.Heading = (ushort)(newHeading & 0xFFF); //patch 0024 expermental if (client.Player.X != newPlayerX || client.Player.Y != newPlayerY) { client.Player.TempProperties.setProperty(LASTMOVEMENTTICK, client.Player.CurrentRegion.Time); } //patch 0024 expermental //client.Player.X = realX; //client.Player.Y = realY; //client.Player.Z = realZ; client.Player.SetCoords(newPlayerX, newPlayerY, newPlayerZ, (ushort)(newHeading & 0xFFF)); //patch 0024 expermental 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; experimental 0024 // 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.IsDiving = ((playerAction & 0x02) != 0); client.Player.TargetInView = ((playerAction & 0x30) != 0); client.Player.GroundTargetInView = ((playerAction & 0x08) != 0); client.Player.IsTorchLighted = ((playerAction & 0x80) != 0); // patch 0069 player diving is 0x02, but will broadcast to other players as 0x04 // if player has a pet summoned, player action is sent by client as 0x04, but sending to other players this is skipped client.Player.IsDiving = ((playerAction & 0x02) != 0); int state = ((playerState >> 10) & 7); client.Player.IsClimbing = (state == 7); client.Player.IsSwimming = (state == 1); //int status = (data & 0x1FF ^ data) >> 8; //int fly = (flyingflag & 0x1FF ^ flyingflag) >> 8; if (state == 3 && client.Player.TempProperties.getProperty <bool>(GamePlayer.DEBUG_MODE_PROPERTY, false) == false && !client.Player.IsAllowedToFly) //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; } } lock (client.Player.LastUniqueLocations) { GameLocation[] locations = client.Player.LastUniqueLocations; GameLocation loc = locations[0]; if (loc.X != newPlayerX || loc.Y != newPlayerY || loc.Z != newPlayerZ || loc.RegionID != client.Player.CurrentRegionID) { loc = locations[locations.Length - 1]; Array.Copy(locations, 0, locations, 1, locations.Length - 1); locations[0] = loc; loc.X = newPlayerX; loc.Y = newPlayerY; loc.Z = newPlayerZ; loc.Heading = client.Player.Heading; loc.RegionID = client.Player.CurrentRegionID; } } //FALLING DAMAGE if (GameServer.ServerRules.CanTakeFallDamage(client.Player) && !client.Player.IsSwimming) { try { int maxLastZ = client.Player.MaxLastZ; // Are we on the ground? if ((fallingDMG >> 15) != 0) { int safeFallLevel = client.Player.GetAbilityLevel(Abilities.SafeFall); int fallSpeed = (newPlayerZSpeed * -1) - (100 * safeFallLevel); int fallDivide = 15; int fallPercent = Math.Min(99, (fallSpeed - (501)) / fallDivide); if (fallSpeed > 500) { client.Out.SendMessage(LanguageMgr.GetTranslation(client.Account.Language, "PlayerPositionUpdateHandler.FallingDamage"), eChatType.CT_Damaged, eChatLoc.CL_SystemWindow); client.Out.SendMessage(string.Format("You take {0}% of you max hits in damage.", fallPercent), eChatType.CT_Damaged, eChatLoc.CL_SystemWindow); client.Out.SendMessage("You lose endurance", eChatType.CT_Damaged, eChatLoc.CL_SystemWindow); client.Player.CalcFallDamage(fallPercent); } client.Player.MaxLastZ = client.Player.Z; } else { if (maxLastZ < client.Player.Z || client.Player.IsRiding || newPlayerZSpeed > -150) // is riding, for dragonflys { client.Player.MaxLastZ = client.Player.Z; } } } catch { log.Warn("error when attempting to calculate fall damage"); } } if (client.Player.Steed != null && client.Player.Steed.ObjectState == GameObject.eObjectState.Active) { client.Player.Heading = client.Player.Steed.Heading; newHeading = (ushort)client.Player.Steed.ObjectID; // test patch 0064 //playerState |= 0x1800; } else if ((playerState >> 10) == 4) // patch 0062 fix bug on release preventing players from receiving res sickness { client.Player.IsSitting = true; } /*else if ((playerState & 0x1000) != 0) //player sitting when releasing on death, dead = 0x1400 * { * client.Player.IsSitting = true; * }*/ GSUDPPacketOut outpak = new GSUDPPacketOut(client.Out.GetPacketCode(eServerPackets.PlayerPosition)); //patch 0069 test to fix player swim out byte flag byte playerOutAction = 0x00; if (client.Player.IsDiving) { playerOutAction |= 0x04; } if (client.Player.TargetInView) { playerOutAction |= 0x30; } if (client.Player.GroundTargetInView) { playerOutAction |= 0x08; } if (client.Player.IsTorchLighted) { playerOutAction |= 0x80; } //stealth is set here if (client.Player.IsStealthed) { playerState |= 0x0200; } outpak.WriteFloatLowEndian(newPlayerX); outpak.WriteFloatLowEndian(newPlayerY); outpak.WriteFloatLowEndian(newPlayerZ); outpak.WriteFloatLowEndian(newPlayerSpeed); outpak.WriteFloatLowEndian(newPlayerZSpeed); outpak.WriteShort(sessionID); outpak.WriteShort(currentZoneID); outpak.WriteShort(playerState); outpak.WriteShort(0); // fall damage flag, dont need to send it outpak.WriteShort(newHeading); outpak.WriteByte(playerOutAction); outpak.WriteByte((byte)(client.Player.RPFlag ? 1 : 0)); outpak.WriteByte(0); outpak.WriteByte((byte)(client.Player.HealthPercent + (client.Player.AttackState ? 0x80 : 0))); outpak.WriteByte(client.Player.ManaPercent); outpak.WriteByte(client.Player.EndurancePercent); //Now copy the whole content of the packet //outpak1119.Write(pak1119, 0, 36); outpak.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; } /* patch 0068 no minotaur logic * 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 // test patch remove players in cache 0065 //player.Client.GameObjectUpdateArray[new Tuple<ushort, ushort>(client.Player.CurrentRegionID, (ushort)client.Player.ObjectID)] = GameTimer.GetTickCount(); player.Out.SendUDPRaw(outpak); } else { player.Out.SendObjectDelete(client.Player); //remove the stealthed player from view } } //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(); } } } }