public void ProcessPacket(int packetID, Player player) { switch ((PacketID)packetID) { case PacketID.entityUpdate: #region entity update var entityUpdate = new EntityUpdate(player.reader); string ACmessage = AntiCheat.Inspect(entityUpdate); if (ACmessage != "ok") { var kickMessage = new ChatMessage() { message = "illegal " + ACmessage }; kickMessage.Write(player.writer, true); Console.WriteLine(player.entityData.name + " kicked for illegal " + kickMessage.message); Thread.Sleep(100); //thread is about to run out anyway so np Kick(player); return; } if (entityUpdate.name != null) { Announce.Join(entityUpdate.name, player.entityData.name, players); } entityUpdate.entityFlags |= 1 << 5; //enable friendly fire flag for pvp if (!player.entityData.IsEmpty) { entityUpdate.Filter(player.entityData); } if (!entityUpdate.IsEmpty) { entityUpdate.Broadcast(players, 0); if (entityUpdate.HP == 0 && player.entityData.HP > 0) { Tomb.Show(player).Broadcast(players, 0); } else if (player.entityData.HP == 0 && entityUpdate.HP > 0) { Tomb.Hide(player).Broadcast(players, 0); } entityUpdate.Merge(player.entityData); } break; #endregion case PacketID.entityAction: #region action EntityAction entityAction = new EntityAction(player.reader); switch (entityAction.type) { case ActionType.talk: break; case ActionType.staticInteraction: //var staticEntity = new StaticEntity(); //staticEntity.chunkX = entityAction.chunkX; //staticEntity.chunkY = entityAction.chunkY; //staticEntity.id = entityAction.index; //staticEntity.type = 0; //staticEntity.position = player.entityData.position; //staticEntity.rotation = 0; //staticEntity.size.x = 2; //staticEntity.size.y = 1; //staticEntity.size.z = 1; //staticEntity.closed = 0; //staticEntity.time = 1000; //staticEntity.guid = player.entityData.guid; //var serverUpdate = new ServerUpdate(); //serverUpdate.statics.Add(staticEntity); //serverUpdate.Send(players, 0); break; case ActionType.pickup: //shouldn't occur since item drops are disabled break; case ActionType.drop: //send item back to dropper because dropping is disabled to prevent chatspam var pickup = new ServerUpdate.Pickup() { guid = player.entityData.guid, item = entityAction.item }; var serverUpdate6 = new ServerUpdate(); serverUpdate6.pickups.Add(pickup); serverUpdate6.Write(player.writer, true); break; case ActionType.callPet: var petItem = player.entityData.equipment[(int)Equipment.pet]; var pet = new EntityUpdate() { guid = 2000 + player.entityData.guid, position = player.entityData.position, hostility = (int)Hostility.pet, entityType = 28, appearance = player.entityData.appearance, HP = 999, parentOwner = 3000 + (long)player.entityData.guid, equipment = player.entityData.equipment, name = "doppelganger" }; pet.Broadcast(players, 0); pet = new EntityUpdate() { guid = 3000 + player.entityData.guid, position = player.entityData.position, hostility = (int)Hostility.pet, entityType = 28, mode = 106, appearance = player.entityData.appearance, HP = 999, parentOwner = (long)player.entityData.guid, equipment = player.entityData.equipment, name = "doppelganger" }; pet.Broadcast(players, 0); break; default: Console.WriteLine("unknown action (" + entityAction.type + ") by " + player.entityData.name); break; } break; #endregion case PacketID.hit: #region hit var hit = new Hit(player.reader); hit.damage *= 0.75f; if (players.ContainsKey(hit.target)) { var serverUpdate7 = new ServerUpdate(); serverUpdate7.hits.Add(hit); serverUpdate7.Broadcast(players, player.entityData.guid); } break; #endregion case PacketID.passiveProc: #region passiveProc var passiveProc = new PassiveProc(player.reader); var serverUpdate8 = new ServerUpdate(); serverUpdate8.passiveProcs.Add(passiveProc); serverUpdate8.Broadcast(players, player.entityData.guid); switch (passiveProc.type) { case ProcType.warFrenzy: case ProcType.camouflage: case ProcType.fireSpark: case ProcType.intuition: case ProcType.elusivenes: case ProcType.swiftness: //nothing particular yet break; case ProcType.manashield: var chatMessage6m = new ChatMessage() { message = string.Format("manashield: {0}", passiveProc.modifier), sender = 0 }; chatMessage6m.Write(player.writer, true); break; case ProcType.bulwalk: var chatMessage6b = new ChatMessage() { message = string.Format("bulwalk: {0}% dmg reduction", 1.0f - passiveProc.modifier), sender = 0 }; chatMessage6b.Write(player.writer, true); break; case ProcType.poison: if (players.ContainsKey(passiveProc.target)) //in case target is a tomb or sth { var poisonDmg = new Hit() { attacker = passiveProc.source, target = passiveProc.target, damage = passiveProc.modifier, position = players[passiveProc.target].entityData.position, type = DamageType.normal }; var poisonTick = new ServerUpdate(); poisonTick.hits.Add(poisonDmg); Poison(poisonTick, passiveProc.duration); } break; default: Console.WriteLine("unknown passiveProc.type: " + passiveProc.type); break; } break; #endregion case PacketID.shoot: #region shoot var shoot = new Shoot(player.reader); var serverUpdate9 = new ServerUpdate(); serverUpdate9.shoots.Add(shoot); serverUpdate9.Broadcast(players, player.entityData.guid); break; #endregion case PacketID.chat: #region chat var chatMessage = new ChatMessage(player.reader) { sender = player.entityData.guid }; if (chatMessage.message.StartsWith("/")) { string parameter = ""; string command = chatMessage.message.Substring(1); if (chatMessage.message.Contains(" ")) { int spaceIndex = command.IndexOf(" "); parameter = command.Substring(spaceIndex + 1); command = command.Substring(0, spaceIndex); } Command.TCP(command, parameter, player); //wip } else { chatMessage.Broadcast(players, 0); Console.ForegroundColor = ConsoleColor.Cyan; Console.Write("#" + player.entityData.guid + " " + player.entityData.name + ": "); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine(chatMessage.message); } break; #endregion case PacketID.chunk: #region chunk var chunk = new Chunk(player.reader); break; #endregion case PacketID.sector: #region sector var sector = new Chunk(player.reader); break; #endregion case PacketID.version: #region version var version = new ProtocolVersion(player.reader); if (version.version != 3) { version.version = 3; version.Write(player.writer, true); player.tcp.Close(); } else { player.entityData.guid = guidCounter; guidCounter++; var join = new Join() { guid = player.entityData.guid, junk = new byte[0x1168] }; join.Write(player.writer, true); var mapSeed = new MapSeed() { seed = Database.mapseed }; mapSeed.Write(player.writer, true); foreach (Player p in players.Values) { p.entityData.Write(player.writer); } players.Add(player.entityData.guid, player); Task.Delay(10000).ContinueWith(t => Load_world_delayed(player)); //WIP, causes crash when player disconnects before executed } break; #endregion default: Console.WriteLine("unknown packet ID: " + packetID); //causes some console spam, but allows resyncing with the player without DC or crash break; } }
public void ProcessDatagram(byte[] datagram, Player source) { switch ((DatagramID)datagram[0]) { case DatagramID.entityUpdate: #region entityUpdate var entityUpdate = new EntityUpdate(datagram); string ACmessage = AntiCheat.Inspect(entityUpdate); if (ACmessage != "ok") { //var kickMessage = new ChatMessage() { // message = "illegal " + ACmessage //}; //kickMessage.Write(player.writer, true); //Console.WriteLine(player.entityData.name + " kicked for illegal " + kickMessage.message); //Thread.Sleep(100); //thread is about to run out anyway so np //Kick(player); //return; } if (entityUpdate.name != null) { //Announce.Join(entityUpdate.name, player.entityData.name, players); } entityUpdate.entityFlags |= 1 << 5; //enable friendly fire flag for pvp if (!source.entityData.IsEmpty) //dont filter the first packet //entityUpdate.Filter(player.entityData); { } if (!entityUpdate.IsEmpty) { //entityUpdate.Broadcast(players, 0); BroadcastUDP(entityUpdate.Data, source); if (entityUpdate.HP == 0 && source.entityData.HP > 0) { BroadcastUDP(Tomb.Show(source).Data); } else if (source.entityData.HP == 0 && entityUpdate.HP > 0) { BroadcastUDP(Tomb.Hide(source).Data); } entityUpdate.Merge(source.entityData); } break; #endregion case DatagramID.attack: #region attack var attack = new Attack(datagram); source.lastTarget = attack.Target; if (players.ContainsKey(attack.Target)) //in case the target is a tombstone { SendUDP(datagram, players[attack.Target]); } break; #endregion case DatagramID.shoot: #region shoot var shoot = new Resources.Datagram.Shoot(datagram); BroadcastUDP(datagram, source); //pass to all players except source break; #endregion case DatagramID.proc: #region proc var proc = new Proc(datagram); switch (proc.Type) { case ProcType.bulwalk: SendUDP(new Chat(string.Format("bulwalk: {0}% dmg reduction", 1.0f - proc.Modifier)).data, source); break; case ProcType.poison: var poisonTickDamage = new Attack() { Damage = proc.Modifier, Target = proc.Target }; var target = players[poisonTickDamage.Target]; Func <bool> tick = () => { bool f = players.ContainsKey(poisonTickDamage.Target); if (f) { SendUDP(poisonTickDamage.data, target); } return(!f); }; Tools.DoLater(tick, 500, 7); //Poison(players[proc.Target], poisonTickDamage); break; case ProcType.manashield: SendUDP(new Chat(string.Format("manashield: {0}", proc.Modifier)).data, source); break; case ProcType.warFrenzy: case ProcType.camouflage: case ProcType.fireSpark: case ProcType.intuition: case ProcType.elusivenes: case ProcType.swiftness: break; default: break; } BroadcastUDP(datagram, source); //pass to all players except source break; #endregion case DatagramID.chat: #region chat var chat = new Chat(datagram); if (chat.Text.StartsWith("/")) { Command.Server(chat.Text, source, this); //wip } else { Console.ForegroundColor = ConsoleColor.Cyan; Console.Write(players[chat.Sender].entityData.name + ": "); Console.ForegroundColor = ConsoleColor.White; Console.WriteLine(chat.Text); BroadcastUDP(datagram, null, true); //pass to all players } break; #endregion case DatagramID.interaction: #region interaction var interaction = new Interaction(datagram); BroadcastUDP(datagram, source); //pass to all players except source break; #endregion case DatagramID.connect: #region connect var connect = new Connect(datagram) { Guid = (ushort)source.entityData.guid, Mapseed = Database.mapseed }; SendUDP(connect.data, source); foreach (Player player in players.Values) { if (player.playing) { SendUDP(player.entityData.Data, source); } } source.playing = true; //Task.Delay(100).ContinueWith(t => Load_world_delayed(source)); //WIP, causes crash when player disconnects before executed Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(source.IpEndPoint.Address + " is now playing"); break; #endregion case DatagramID.disconnect: #region disconnect var disconnect = new Disconnect(datagram); source.playing = false; BroadcastUDP(datagram, source, true); source.entityData = new EntityUpdate() { guid = source.entityData.guid }; Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine(source.IpEndPoint.Address + " is now lurking"); break; #endregion case DatagramID.specialMove: #region specialMove var specialMove = new SpecialMove(datagram); switch (specialMove.Id) { case SpecialMoveID.taunt: var targetGuid = specialMove.Guid; specialMove.Guid = (ushort)source.entityData.guid; SendUDP(specialMove.data, players[targetGuid]); break; case SpecialMoveID.cursedArrow: case SpecialMoveID.arrowRain: case SpecialMoveID.shrapnel: case SpecialMoveID.smokeBomb: case SpecialMoveID.iceWave: case SpecialMoveID.confusion: case SpecialMoveID.shadowStep: BroadcastUDP(specialMove.data, source); break; default: break; } break; #endregion case DatagramID.dummy: break; default: Console.WriteLine("unknown DatagramID: " + datagram[0]); break; } }