public static bool OnGreetPlayer(int playerId) { #if Full_API var player = Main.player[playerId]; var ctx = new HookContext { Connection = player.Connection.Socket, Player = player, Sender = player }; var args = new HookArgs.PlayerPreGreeting { Slot = playerId, Motd = String.IsNullOrEmpty(Main.motd) ? (Lang.mp[18] + " " + Main.worldName) : Main.motd, MotdColour = new Microsoft.Xna.Framework.Color(255, 240, 20) }; HookPoints.PlayerPreGreeting.Invoke(ref ctx, ref args); if (ctx.CheckForKick()) { return(false); } player.SendMessage(args.Motd, 255, args.MotdColour.R, args.MotdColour.G, args.MotdColour.B); string list = ""; for (int i = 0; i < 255; i++) { if (Main.player[i].active) { if (list == "") { list += Main.player[i].name; } else { list = list + ", " + Main.player[i].Name; } } } player.SendMessage("Current players: " + list + ".", 255, 255, 240, 20); Tools.WriteLine("{0} @ {1}: ENTER {2}", Netplay.Clients[playerId].Socket.GetRemoteAddress(), playerId, player.name); var args2 = new HookArgs.PlayerEnteredGame { Slot = playerId }; ctx.SetResult(HookResult.DEFAULT, false); HookPoints.PlayerEnteredGame.Invoke(ref ctx, ref args2); ctx.CheckForKick(); #endif return(false); //We implemented our own, so do not continue on with vanilla }
public override void Process(ClientConnection conn, byte[] readBuffer, int length, int num) { //var data = Encoding.ASCII.GetString (readBuffer, num, length - 1); //var lines = data.Split ('\n'); //foreach (var line in lines) //{ // if (line == "tdcm1") // { // //player.HasClientMod = true; // ProgramLog.Log ("{0} is a TDCM protocol version 1 client.", conn.RemoteAddress); // } // else if (line == "tdsmcomp1") // { // conn.CompressionVersion = 1; // ProgramLog.Log ("{0} supports TDSM compression version 1.", conn.RemoteAddress); // } //} ReadString(readBuffer); var ctx = new HookContext { Connection = conn, }; var args = new HookArgs.DisconnectReceived { }; HookPoints.DisconnectReceived.Invoke(ref ctx, ref args); ctx.CheckForKick(); }
public override void Process(int whoAmI, byte[] readBuffer, int length, int num) { int x = BitConverter.ToInt32(readBuffer, num); num += 4; int y = BitConverter.ToInt32(readBuffer, num); num += 4; var player = Main.players[whoAmI]; if (Math.Abs(player.Position.X / 16 - x) >= 7 || Math.Abs(player.Position.Y / 16 - y) >= 7) { return; } int chestIndex = Chest.FindChest(x, y); var ctx = new HookContext { Connection = player.Connection, Player = player, Sender = player, }; var args = new HookArgs.ChestOpenReceived { X = x, Y = y, ChestIndex = (short)chestIndex, }; HookPoints.ChestOpenReceived.Invoke(ref ctx, ref args); if (ctx.CheckForKick()) { return; } if (ctx.Result == HookResult.IGNORE) { return; } if (ctx.Result == HookResult.DEFAULT && chestIndex > -1) { var user = Chest.UsingChest(chestIndex); if (user >= 0 && user != whoAmI) { return; } for (int i = 0; i < Chest.MAX_ITEMS; i++) { NetMessage.SendData(32, whoAmI, -1, "", chestIndex, (float)i); } NetMessage.SendData(33, whoAmI, -1, "", chestIndex); Main.players[whoAmI].chest = chestIndex; return; } }
public ClientConnection(Socket sock) : base(sock) { if (SlotId == 0) { SlotId = -1; } var remoteEndPoint = (IPEndPoint)sock.RemoteEndPoint; _remoteAddress = new TcpAddress(remoteEndPoint.Address, remoteEndPoint.Port); sock.LingerState = new LingerOption(true, 10); var ctx = new HookContext { Connection = this }; var args = new HookArgs.NewConnection(); HookPoints.NewConnection.Invoke(ref ctx, ref args); if (ctx.CheckForKick()) { return; } _isReceiving = true; //The connection was established, so we can begin reading }
public override void Process(int whoAmI, byte[] readBuffer, int length, int num) { short identity = BitConverter.ToInt16(readBuffer, num); num += 2; byte owner = readBuffer[num]; owner = (byte)whoAmI; int index = Projectile.FindExisting(identity, owner); if (index == 1000) { return; } var player = Main.players[whoAmI]; var ctx = new HookContext { Connection = player.Connection, Player = player, Sender = player, }; var args = new HookArgs.KillProjectileReceived { Id = identity, Owner = owner, Index = (short)index, }; HookPoints.KillProjectileReceived.Invoke(ref ctx, ref args); if (ctx.CheckForKick()) { return; } if (ctx.Result == HookResult.IGNORE) { return; } if (ctx.Result == HookResult.RECTIFY) { var msg = NetMessage.PrepareThreadInstance(); msg.Projectile(Main.projectile[index]); msg.Send(whoAmI); return; } var projectile = Main.projectile[index]; if (projectile.Owner == owner && projectile.identity == identity) { projectile.Kill(); NetMessage.SendData(29, -1, whoAmI, "", (int)identity, (float)owner); } }
public override void Process(int whoAmI, byte[] readBuffer, int length, int num) //TODO: redesign signs { int start = num - 1; short signIndex = BitConverter.ToInt16(readBuffer, num); num += 2; int x = BitConverter.ToInt32(readBuffer, num); num += 4; int y = BitConverter.ToInt32(readBuffer, num); num += 4; short existing = (short)Sign.ReadSign(x, y); if (existing >= 0) { signIndex = existing; } string SignText; if (!ParseString(readBuffer, num, length - num + start, out SignText)) { return; // invalid characters } var player = Main.players[whoAmI]; var ctx = new HookContext { Connection = player.Connection, Sender = player, Player = player, }; var args = new HookArgs.SignTextSet { X = x, Y = y, SignIndex = signIndex, Text = SignText, OldSign = Main.sign[signIndex], }; HookPoints.SignTextSet.Invoke(ref ctx, ref args); if (ctx.CheckForKick() || ctx.Result == HookResult.IGNORE) { return; } if (Main.sign[signIndex] == null) { Main.sign[signIndex] = new Sign(); } Main.sign[signIndex].x = args.X; Main.sign[signIndex].y = args.Y; Sign.TextSign(signIndex, args.Text); }
public bool Read(int bufferId, int start, int length) { var buffer = NetMessage.buffer[bufferId]; var x = (int)buffer.reader.ReadInt16(); var y = (int)buffer.reader.ReadInt16(); var colour = buffer.reader.ReadByte(); if (!WorldGen.InWorld(x, y, 3)) { return(true); } var player = Main.player[bufferId]; var ctx = new HookContext { Connection = player.Connection.Socket, Sender = player, Player = player, }; var args = new TDSMHookArgs.PaintWall { X = x, Y = y, Colour = colour }; TDSMHookPoints.PaintWall.Invoke(ref ctx, ref args); if (ctx.CheckForKick()) { return(true); } if (ctx.Result == HookResult.IGNORE) { return(true); } if (ctx.Result == HookResult.RECTIFY) { NetMessage.SendTileSquare(bufferId, x, y, 1); return(true); } WorldGen.paintWall(x, y, colour, false); if (Main.netMode == 2) { NetMessage.SendData(64, -1, bufferId, "", x, (float)y, (float)colour, 0f, 0, 0, 0); } return(true); }
public override void Process(int whoAmI, byte[] readBuffer, int length, int num) { int start = num - 1; int playerIndex = ReadByte(readBuffer); if (playerIndex != whoAmI && Entry.EnableCheatProtection) { Terraria.Netplay.Clients[whoAmI].Kick("Cheating detected (KILL_PLAYER forgery)."); return; } var player = Main.player[whoAmI]; var ctx = new HookContext { Connection = (Terraria.Netplay.Clients[whoAmI] as ServerSlot).conn, Sender = player, Player = player, }; var args = new HookArgs.ObituaryReceived { Direction = (int)ReadByte(readBuffer) - 1, Damage = ReadInt16(readBuffer), PvpFlag = ReadByte(readBuffer) }; //string obituary; //if (!ParseString(readBuffer, num + 1, length - num - 1 + start, out obituary)) //{ // tdsm.api.Callbacks.Netplay.slots[whoAmI].Kick("Invalid characters in obituary message."); // return; //} args.Obituary = " " + ReadString(readBuffer); HookPoints.ObituaryReceived.Invoke(ref ctx, ref args); if (ctx.CheckForKick()) { return; } if (ctx.Result == HookResult.IGNORE) { return; } ProgramLog.Log("{0} @ {1}: [Death] {2}{3}", player.IPAddress, whoAmI, player.Name ?? "<null>", args.Obituary); player.KillMe(args.Damage, args.Direction, args.PvpFlag == 1, args.Obituary); NewNetMessage.SendData(44, -1, whoAmI, args.Obituary, whoAmI, args.Direction, args.Damage, args.PvpFlag); }
public override void Process(int whoAmI, byte[] readBuffer, int length, int num) { int start = num - 1; int playerIndex = readBuffer[num++]; if (playerIndex != whoAmI) { NetPlay.slots[whoAmI].Kick("Cheating detected (KILL_PLAYER forgery)."); return; } var player = Main.players[whoAmI]; var ctx = new HookContext { Connection = NetPlay.slots[whoAmI].conn, Sender = player, Player = player, }; var args = new HookArgs.ObituaryReceived { Direction = (int)readBuffer[num++] - 1, Damage = BitConverter.ToInt16(readBuffer, num++), PvpFlag = readBuffer[++num] }; string obituary; if (!ParseString(readBuffer, num + 1, length - num - 1 + start, out obituary)) { NetPlay.slots[whoAmI].Kick("Invalid characters in obituary message."); return; } args.Obituary = obituary; HookPoints.ObituaryReceived.Invoke(ref ctx, ref args); if (ctx.CheckForKick()) { return; } if (ctx.Result == HookResult.IGNORE) { return; } ProgramLog.Death.Log("{0} @ {1}: [Death] {2}{3}", player.IPAddress, whoAmI, player.Name ?? "<null>", args.Obituary); player.KillMe(args.Damage, args.Direction, args.PvpFlag == 1, args.Obituary); NetMessage.SendData(44, -1, whoAmI, args.Obituary, whoAmI, args.Direction, args.Damage, args.PvpFlag); }
public override void Process(int whoAmI, byte[] readBuffer, int length, int num) { int x = BitConverter.ToInt32(readBuffer, num); num += 4; int y = BitConverter.ToInt32(readBuffer, num); if (Main.tile.At(x, y).Type != 21) { return; } var player = Main.players[whoAmI]; var ctx = new HookContext { Connection = player.Connection, Player = player, Sender = player, }; var args = new HookArgs.ChestBreakReceived { X = x, Y = y, }; HookPoints.ChestBreakReceived.Invoke(ref ctx, ref args); if (ctx.CheckForKick()) { return; } if (ctx.Result == HookResult.IGNORE) { return; } if (ctx.Result == HookResult.RECTIFY) { NetMessage.SendTileSquare(whoAmI, x, y, 3); return; } WorldModify.KillTile(null, null, x, y); if (!Main.tile.At(x, y).Active || Main.tile.At(x, y).Type != 21) { NetMessage.SendData(17, -1, -1, "", 0, (float)x, (float)y); } }
public override void Process(int whoAmI, byte[] readBuffer, int length, int num) { int playerIndex = ReadByte(readBuffer); if (playerIndex != whoAmI && Entry.EnableCheatProtection) { Terraria.Netplay.Clients[whoAmI].Kick("Cheating detected (PLAYER_PVP_CHANGE forgery)."); return; } var pvp = ReadByte(readBuffer) == 1; var player = Main.player[whoAmI]; var ctx = new HookContext { Connection = player.Connection, Player = player, Sender = player, }; var args = new HookArgs.PvpSettingReceived { PvpFlag = pvp, }; HookPoints.PvpSettingReceived.Invoke(ref ctx, ref args); if (ctx.CheckForKick()) { return; } if (ctx.Result == HookResult.IGNORE) { return; } if (ctx.Result == HookResult.RECTIFY) { NewNetMessage.SendData(30, whoAmI, -1, String.Empty, whoAmI); return; } player.hostile = pvp; string message = (player.hostile) ? " has enabled PvP!" : " has disabled PvP!"; NewNetMessage.SendData(30, -1, whoAmI, String.Empty, whoAmI); NewNetMessage.SendData(25, -1, -1, player.Name + message, 255, (float)Main.teamColor[player.team].R, (float)Main.teamColor[player.team].G, (float)Main.teamColor[player.team].B); }
public static void OnPlayerJoined(Player player) { var ctx = new HookContext { Connection = player.Connection, Player = player, Sender = player }; var args = new HookArgs.PlayerEnteredGame { Slot = player.whoAmI }; ctx.SetResult(HookResult.DEFAULT, false); HookPoints.PlayerEnteredGame.Invoke(ref ctx, ref args); ctx.CheckForKick(); }
public override void Process(int whoAmI, byte[] readBuffer, int length, int num) { int playerId = readBuffer[num++]; byte action = readBuffer[num]; if (playerId != whoAmI) { Main.players[whoAmI].Kick("SummonSkeletron Player Forgery."); return; } if (action == 1) { var player = Main.players[whoAmI]; var ctx = new HookContext { Connection = player.Connection, Sender = player, Player = player, }; var args = new HookArgs.PlayerTriggeredEvent { Type = WorldEventType.BOSS, Name = "Skeletron", }; HookPoints.PlayerTriggeredEvent.Invoke(ref ctx, ref args); if (ctx.CheckForKick() || ctx.Result == HookResult.IGNORE) { return; } //ProgramLog.Users.Log ("{0} @ {1}: Skeletron summoned by {2}.", player.IPAddress, whoAmI, player.Name); //NetMessage.SendData (Packet.PLAYER_CHAT, -1, -1, string.Concat (player.Name, " has summoned Skeletron!"), 255, 255, 128, 150); NPC.SpawnSkeletron(player); } else if (action == 2) { NetMessage.SendData(51, -1, whoAmI, "", playerId, action, 0f, 0f, 0); } }
public bool Read(int bufferId, int start, int length) { var buffer = NetMessage.buffer[bufferId]; var player = Main.player[bufferId]; if (Main.netMode != 2) { return(true); } int x = (int)buffer.reader.ReadInt16(); int y = (int)buffer.reader.ReadInt16(); int id = Sign.ReadSign(x, y, true); if (id >= 0) { var ctx = new HookContext { Connection = player.Connection.Socket, Sender = player, Player = player }; var args = new TDSMHookArgs.SignTextGet { X = x, Y = y, SignIndex = (short)id, Text = (id >= 0 && Main.sign[id] != null) ? Main.sign[id].text : null, }; TDSMHookPoints.SignTextGet.Invoke(ref ctx, ref args); if (ctx.CheckForKick() || ctx.Result == HookResult.IGNORE) { return(true); } if (args.Text != null) { NetMessage.SendData(47, bufferId, -1, "", id, (float)bufferId, 0, 0, 0, 0, 0); } } return(true); }
public bool Read(int bufferId, int start, int length) { var buffer = NetMessage.buffer[bufferId]; int npcId = (int)buffer.reader.ReadInt16(); int playerId = (int)buffer.reader.ReadByte(); if (Main.netMode == 2) { playerId = bufferId; } var ply = Main.player[playerId]; var ctx = new HookContext() { Sender = ply, Player = ply }; var args = new TDSMHookArgs.NpcHurtReceived() { Victim = Terraria.Main.npc[npcId], Damage = ply.inventory[ply.selectedItem].damage, HitDirection = ply.direction, Knockback = ply.inventory[ply.selectedItem].knockBack, Critical = false }; TDSMHookPoints.NpcHurtReceived.Invoke(ref ctx, ref args); if (ctx.CheckForKick() || ctx.Result == HookResult.IGNORE) { return(true); } Terraria.Main.npc[npcId].StrikeNPC(args.Damage, args.Knockback, args.HitDirection, false, false, false); if (Main.netMode == 2) { NetMessage.SendData(24, -1, bufferId, "", npcId, (float)playerId, 0, 0, 0, 0, 0); NetMessage.SendData(23, -1, -1, "", npcId, 0, 0, 0, 0, 0, 0); } return(true); }
public override void Process(int whoAmI, byte[] readBuffer, int length, int num) { int x = BitConverter.ToInt32(readBuffer, num); num += 4; int y = BitConverter.ToInt32(readBuffer, num); num += 4; int signIndex = Sign.ReadSign(x, y); var player = Main.players[whoAmI]; var ctx = new HookContext { Connection = player.Connection, Sender = player, Player = player, }; var args = new HookArgs.SignTextGet { X = x, Y = y, SignIndex = (short)signIndex, Text = (signIndex >= 0 && Main.sign[signIndex] != null) ? Main.sign[signIndex].text : null, }; HookPoints.SignTextGet.Invoke(ref ctx, ref args); if (ctx.CheckForKick() || ctx.Result == HookResult.IGNORE) { return; } if (args.Text != null) { var msg = NetMessage.PrepareThreadInstance(); msg.WriteSign(signIndex, x, y, args.Text); msg.Send(whoAmI); } }
public static void OnPlayerEntering(Player player) { #if Full_API var ctx = new HookContext { Player = player, Sender = player }; var args = new HookArgs.PlayerEnteringGame { Slot = player.whoAmI }; ctx.SetResult(HookResult.DEFAULT, false); HookPoints.PlayerEnteringGame.Invoke(ref ctx, ref args); if (!ctx.CheckForKick()) { NetMessage.SendData(4, -1, player.whoAmI, player.name, player.whoAmI, 0f, 0f, 0f, 0, 0, 0); } #endif }
public override void Process(int whoAmI, byte[] readBuffer, int length, int num) { if (readBuffer[num++] != whoAmI) { NetPlay.slots[whoAmI].Kick("Cheating detected (PLAYER_STATE_UPDATE forgery)."); return; } var player = Main.players[whoAmI]; var ctx = new HookContext { Connection = player.Connection, Sender = player, Player = player, }; var args = new HookArgs.StateUpdateReceived(); args.Parse(readBuffer, num); HookPoints.StateUpdateReceived.Invoke(ref ctx, ref args); if (ctx.CheckForKick()) { return; } player.oldVelocity = player.Velocity; args.ApplyParams(player); args.ApplyKeys(player); player.fallStart = (int)(player.Position.Y / 16f); if (NetPlay.slots[whoAmI].state == SlotState.PLAYING) { NetMessage.SendData(13, -1, whoAmI, "", whoAmI); } }
public ClientConnection(Socket socket, int slot) : base(socket) { //var buf = NewNetMessage.buffer[id]; //socket.SendBufferSize = 128000; connectedAt = time.Elapsed; if (slot >= 0) { AssignSlot(slot); } socket.LingerState = new LingerOption(true, 10); var ctx = new HookContext { Connection = this }; var args = new HookArgs.NewConnection(); HookPoints.NewConnection.Invoke(ref ctx, ref args); if (ctx.CheckForKick()) { return; } lock (All) { indexInAll = All.Count; All.Add(this); } StartReceiving(new byte[4192]); }
public override void Process(ClientConnection conn, byte[] readBuffer, int length, int num) { int start = num - 1; string password = Encoding.ASCII.GetString(readBuffer, num, length - num + start); if (conn.State == SlotState.SERVER_AUTH) { var ctx = new HookContext { Connection = conn, }; var args = new HookArgs.ServerPassReceived { Password = password, }; HookPoints.ServerPassReceived.Invoke(ref ctx, ref args); if (ctx.CheckForKick()) { return; } if (ctx.Result == HookResult.ASK_PASS) { var msg = NetMessage.PrepareThreadInstance(); msg.PasswordRequest(); conn.Send(msg.Output); } else if (ctx.Result == HookResult.CONTINUE || password == NetPlay.password) { conn.State = SlotState.ACCEPTED; var msg = NetMessage.PrepareThreadInstance(); msg.ConnectionResponse(253 /* dummy value, real slot assigned later */); conn.Send(msg.Output); return; } conn.Kick("Incorrect server password."); } else if (conn.State == SlotState.PLAYER_AUTH) { var name = conn.Player.Name ?? ""; var ctx = new HookContext { Connection = conn, Player = conn.Player, Sender = conn.Player, }; var args = new HookArgs.PlayerPassReceived { Password = password, }; HookPoints.PlayerPassReceived.Invoke(ref ctx, ref args); if (ctx.CheckForKick()) { return; } if (ctx.Result == HookResult.ASK_PASS) { var msg = NetMessage.PrepareThreadInstance(); msg.PasswordRequest(); conn.Send(msg.Output); } else // HookResult.DEFAULT { var lower = name.ToLower(); bool reserved = false; //conn.Queue = (int)loginEvent.Priority; foreach (var otherPlayer in Main.players) { //var otherSlot = Netplay.slots[otherPlayer.whoAmi]; var otherConn = otherPlayer.Connection; if (otherPlayer.Name != null && lower == otherPlayer.Name.ToLower() && otherConn != null && otherConn.State >= SlotState.CONNECTED) { if (!reserved) { reserved = SlotManager.HandoverSlot(otherConn, conn); } otherConn.Kick("Replaced by new connection."); } } //conn.State = SlotState.SENDING_WORLD; if (!reserved) // reserved slots get assigned immediately during the kick { SlotManager.Schedule(conn, conn.DesiredQueue); } //NetMessage.SendData (4, -1, whoAmI, name, whoAmI); // broadcast player data now // replay packets from side buffer //conn.conn.ProcessSideBuffer (); //var buf = NetMessage.buffer[whoAmI]; //NetMessage.CheckBytes (whoAmI, buf.sideBuffer, ref buf.sideBufferBytes, ref buf.sideBufferMsgLen); //buf.ResetSideBuffer (); //NetMessage.SendData (7, whoAmI); // continue with world data } } }
public override void Process(ClientConnection conn, byte[] readBuffer, int length, int num) { // ServerSlot slot = Netplay.slots[whoAmI]; // PlayerLoginEvent loginEvent = new PlayerLoginEvent(); // loginEvent.Slot = slot; // loginEvent.Sender = Main.players[whoAmI]; // Server.PluginManager.processHook(Plugin.Hooks.PLAYER_PRELOGIN, loginEvent); // if ((loginEvent.Cancelled || loginEvent.Action == PlayerLoginAction.REJECT) && (slot.state & SlotState.DISCONNECTING) == 0) // { // slot.Kick ("Disconnected by server."); // return; // } string clientName = conn.RemoteAddress.Split(':')[0]; // // if (Server.BanList.containsException(clientName)) // { // slot.Kick ("You are banned from this Server."); // return; // } if (Program.properties.UseWhiteList && !Server.WhiteList.containsException(clientName)) { conn.Kick("You are not on the WhiteList."); return; } string version = Networking.StringCache.FindOrMake(new ArraySegment <byte> (readBuffer, num, length - 1)); var ctx = new HookContext { Connection = conn, }; var args = new HookArgs.ConnectionRequestReceived { Version = version, }; HookPoints.ConnectionRequestReceived.Invoke(ref ctx, ref args); if (ctx.CheckForKick()) { return; } if (ctx.Result == HookResult.DEFAULT && !(version == "Terraria" + Statics.CURRENT_TERRARIA_RELEASE)) { if (version.Length > 30) { version = version.Substring(0, 30); } ProgramLog.Debug.Log("Client version string: {0}", version); conn.Kick(string.Concat("This server requires Terraria ", Program.VERSION_NUMBER)); return; } var msg = NetMessage.PrepareThreadInstance(); if (ctx.Result == HookResult.ASK_PASS || (NetPlay.password != null && NetPlay.password != "")) { conn.State = SlotState.SERVER_AUTH; msg.PasswordRequest(); conn.Send(msg.Output); return; } conn.State = SlotState.ACCEPTED; msg.ConnectionResponse(253 /* arbitrary fake value, true slot assigned later */); conn.Send(msg.Output); }
public override void Process(int whoAmI, byte[] readBuffer, int length, int num) { short projectileIdentity = BitConverter.ToInt16(readBuffer, num); num += 2; float x = BitConverter.ToSingle(readBuffer, num); num += 4; float y = BitConverter.ToSingle(readBuffer, num); num += 4; float vX = BitConverter.ToSingle(readBuffer, num); num += 4; float vY = BitConverter.ToSingle(readBuffer, num); num += 4; float knockBack = BitConverter.ToSingle(readBuffer, num); num += 4; short damage = BitConverter.ToInt16(readBuffer, num); num += 2; byte projectileOwner = readBuffer[num++]; byte type = readBuffer[num++]; if (projectileOwner != whoAmI) { #if DEBUG_PROJECTILES ProgramLog.Debug.Log("Ignoring unowned projectile from {0} ({1})", whoAmI, projectileOwner); #endif return; } if (Projectile.MAX_AI != 2) { throw new Exception("Projectile receiving code hasn't been updated!"); } var ai0 = BitConverter.ToSingle(readBuffer, num); num += 4; var ai1 = BitConverter.ToSingle(readBuffer, num); var player = Main.players[whoAmI]; var projectileIndex = Projectile.FindExisting(projectileIdentity, projectileOwner); var ctx = new HookContext { Connection = player.Connection, Player = player, Sender = player, }; var args = new HookArgs.ProjectileReceived { X = x, Y = y, VX = vX, VY = vY, Id = projectileIdentity, Owner = projectileOwner, Knockback = knockBack, Damage = damage, TypeByte = type, AI_0 = ai0, AI_1 = ai1, ExistingIndex = projectileIndex < 1000 ? projectileIndex : -1, }; if (projectileIndex == 1000 && args.Type.IsHighExplosive() && ai0 > 0.0) { // probably a lagged update from a repossessed projectile #if DEBUG_PROJECTILES ProgramLog.Debug.Log("Ignoring old update for repossessed projectile."); #endif var msg = NetMessage.PrepareThreadInstance(); msg.EraseProjectile(projectileIdentity, projectileOwner); msg.Send(whoAmI); return; } HookPoints.ProjectileReceived.Invoke(ref ctx, ref args); if (ctx.CheckForKick()) { args.CleanupProjectile(); return; } if (ctx.Result == HookResult.IGNORE) { args.CleanupProjectile(); return; } if (ctx.Result == HookResult.RECTIFY) { args.CleanupProjectile(); if (projectileIndex < 1000) { var msg = NetMessage.PrepareThreadInstance(); msg.Projectile(Main.projectile[projectileIndex]); msg.Send(whoAmI); return; } else { ctx.SetResult(HookResult.ERASE); } } if (ctx.Result == HookResult.ERASE) { args.CleanupProjectile(); var msg = NetMessage.PrepareThreadInstance(); msg.EraseProjectile(projectileIdentity, projectileOwner); msg.Send(whoAmI); return; } if (ctx.Result != HookResult.CONTINUE) { if (type > Projectile.MAX_PROJECTILES) { args.CleanupProjectile(); NetPlay.slots[whoAmI].Kick("Invalid projectile."); return; } else if (type == (int)ProjectileType.N38_HARPY_FEATHER || type == (int)ProjectileType.N55_STINGER || type == (int)ProjectileType.N44_DEMON_SICKLE) { args.CleanupProjectile(); NetPlay.slots[whoAmI].Kick("Projectile cheat detected."); return; } else if (type == (int)ProjectileType.N23_HARPOON) { args.CleanupProjectile(); if (Math.Abs(vX) + Math.Abs(vY) < 1e-4) // ideally, we'd want to figure out all projectiles that never have 0 velocity { NetPlay.slots[whoAmI].Kick("Harpoon cheat detected."); return; } } } Projectile projectile; if (args.ExistingIndex >= 0) { #if DEBUG_PROJECTILES ProgramLog.Debug.Log("Updated projectile {0} ({1}/{2}/{3}) ({4}/{5})", projectileIndex, projectileOwner, projectileIdentity, args.Type, ai0, ai1); #endif args.CleanupProjectile(); projectile = Main.projectile[args.ExistingIndex]; args.Apply(projectile); } else { projectile = args.CreateProjectile(); if (projectile == null) { //ProgramLog.Debug.Log ("No slots left for projectile ({1}/{2}/{3})", projectileOwner, projectileIdentity, args.Type); return; } projectileIndex = projectile.whoAmI; #if DEBUG_PROJECTILES ProgramLog.Debug.Log("Created projectile {0} ({1}/{2}/{3}) ({4}/{5})", projectileIndex, projectileOwner, projectileIdentity, args.Type, ai0, ai1); #endif } if (args.Type.IsHighExplosive()) { #if DEBUG_PROJECTILES ProgramLog.Debug.Log("Repossessing projectile ({0}, {1}, {2}, {3}).", vX, vY, ai0, ai1); #endif // transfer ownership //var msg = NetMessage.PrepareThreadInstance (); //msg.EraseProjectile (projectileIdentity, projectileOwner); //projectile.Repossess (); //msg.Projectile (projectile); //msg.Send (whoAmI); /* temp, Until Repossessing is complete, At the moment if killed by a repossessed projectile * the client wont be killed, the death text will fire once, thereafter they cannot * be killed via explosives. */ if (Server.RejectedItems.Contains(args.TypeByte.ToString()) || Server.RejectedItems.Contains(projectile.Name) || !Program.properties.AllowExplosions) { var msg = NetMessage.PrepareThreadInstance(); msg.EraseProjectile(projectileIdentity, projectileOwner); msg.Send(whoAmI); } } // int projectileIndex = getProjectileIndex(projectileOwner, projectileIdentity); // Projectile oldProjectile = Main.projectile[projectileIndex]; // if (!oldProjectile.Active || projectile.type != oldProjectile.type) // { // NetPlay.slots[whoAmI].spamProjectile += 1f; // } // if (playerEvent.Cancelled || (!Program.properties.AllowExplosions && // ( type == (int)ProjectileType.BOMB /* 28 */ || // type == (int)ProjectileType.DYNAMITE /* 29 */ || // type == (int)ProjectileType.BOMB_STICKY /* 37 */ // ) && !Main.players[whoAmI].Op)) // { // // erase the projectile client-side // projectile.Position.X = -1000; // projectile.Position.Y = -1000; // projectile.type = ProjectileType.UNKNOWN; // // var msg = NetMessage.PrepareThreadInstance (); // msg.Projectile (projectile); // msg.Send (whoAmI); // // return; // } Main.projectile[projectileIndex] = projectile; NetMessage.SendData(27, -1, whoAmI, "", projectileIndex); }
public static void OnPlayerJoined(int plr) { var player = Main.player[plr]; var ctx = new HookContext { Connection = player.Connection, Player = player, Sender = player, }; var args = new HookArgs.PlayerEnteringGame { Slot = plr, }; HookPoints.PlayerEnteringGame.Invoke(ref ctx, ref args); if (ctx.CheckForKick()) { return; } var msg = NewNetMessage.PrepareThreadInstance(); if (ctx.Result == HookResult.DEFAULT) { var motd = (Main.motd ?? System.String.Empty).Split('@'); //"My greeting from properties".Split('@'); for (int i = 0; i < motd.Length; i++) { if (motd[i] != null && motd[i].Trim().Length > 0) { msg.PlayerChat(255, motd[i], 0, 0, 255); } } string list = System.String.Empty; for (int i = 0; i < 255; i++) { if (Main.player[i].active) { if (list == System.String.Empty) { list += Main.player[i].name; } else { list = list + ", " + Main.player[i].name; } } } msg.PlayerChat(255, "Current players: " + list + ".", 255, 240, 20); msg.Send(plr); // send these before the login event, so messages from plugins come after } var slot = Terraria.Netplay.Clients[plr] as ServerSlot; slot.announced = true; // to player msg.Clear(); msg.SyncAllNPCHomes(); msg.SendSyncOthersForPlayer(plr); ProgramLog.Log("{0} @ {1}: ENTER {2}", slot.remoteAddress, plr, player.name); //if (player.HasHackedData()) //{ // player.Kick("No Hacked Health or Mana is allowed."); // return; //} // to other players msg.Clear(); msg.PlayerChat(255, player.name + " has joined.", 255, 240, 20); msg.ReceivingPlayerJoined(plr); msg.SendSyncPlayerForOthers(plr); // broadcasts the preceding message too var args2 = new HookArgs.PlayerEnteredGame { Slot = plr, }; ctx.SetResult(HookResult.DEFAULT, false); HookPoints.PlayerEnteredGame.Invoke(ref ctx, ref args2); if (ctx.CheckForKick()) { return; } }
public void ParseAndProcess(ISender sender, string line) { var ctx = new HookContext { Sender = sender, #if Full_API Player = sender as Player #endif }; #if Full_API ctx.Connection = ctx.Player != null ? ctx.Player.Connection.Socket : null; #endif var hargs = new HookArgs.Command(); try { CommandInfo info; var firstSpace = line.IndexOf(' '); if (firstSpace < 0) { firstSpace = line.Length; } var prefix = line.Substring(0, firstSpace); hargs.Prefix = prefix; if (FindStringCommand(prefix, out info)) { hargs.ArgumentString = (firstSpace < line.Length - 1 ? line.Substring(firstSpace + 1, line.Length - firstSpace - 1) : "").Trim(); HookPoints.Command.Invoke(ref ctx, ref hargs); if (ctx.CheckForKick() || ctx.Result == HookResult.IGNORE) { return; } if (ctx.Result != HookResult.CONTINUE && !CheckAccessLevel(info, sender)) { sender.SendMessage("Permissions error", 255, 238, 130, 238); return; } try { info.Run(sender, hargs.ArgumentString); } catch (NLua.Exceptions.LuaScriptException e) { if (e.IsNetException) { var ex = e.GetBaseException(); if (ex != null) { if (ex is CommandError) { sender.SendMessage(prefix + ": " + ex.Message); info.ShowHelp(sender); } } } } catch (ExitException e) { throw e; } catch (CommandError e) { sender.SendMessage(prefix + ": " + e.Message); info.ShowHelp(sender); } return; } var args = new ArgumentList(); var command = Tokenize(line, args); if (command != null) { if (FindTokenCommand(command, out info)) { hargs.Arguments = args; foreach (BasePlugin plg in PluginManager._plugins.Values) { if (plg.commands.ContainsKey(command)) { args.Plugin = plg; } } HookPoints.Command.Invoke(ref ctx, ref hargs); if (ctx.CheckForKick() || ctx.Result == HookResult.IGNORE) { return; } if (ctx.Result != HookResult.CONTINUE && !CheckAccessLevel(info, sender)) { sender.SendMessage("Permissions error", 255, 238, 130, 238); return; } try { info.Run(sender, hargs.Arguments); } catch (NLua.Exceptions.LuaScriptException e) { if (e.IsNetException) { var ex = e.GetBaseException(); if (ex != null) { if (ex is CommandError) { sender.SendMessage(command + ": " + ex.Message); info.ShowHelp(sender); } } } } catch (ExitException e) { throw e; } catch (CommandError e) { sender.SendMessage(command + ": " + e.Message); info.ShowHelp(sender); } return; } else { sender.SendMessage(String.Format("No such command '{0}'.", command)); } } } catch (ExitException e) { throw e; } catch (TokenizerException e) { sender.SendMessage(e.Message); } }
public void ParseAndProcess(ISender sender, string line) { var ctx = new HookContext { Sender = sender, Player = sender as Player, }; ctx.Connection = ctx.Player != null ? ctx.Player.Connection : null; var hargs = new HookArgs.Command(); try { CommandInfo info; var firstSpace = line.IndexOf(' '); if (firstSpace < 0) { firstSpace = line.Length; } var prefix = line.Substring(0, firstSpace); hargs.Prefix = prefix; if (FindStringCommand(prefix, out info)) { hargs.ArgumentString = (firstSpace < line.Length - 1 ? line.Substring(firstSpace + 1, line.Length - firstSpace - 1) : "").Trim(); HookPoints.Command.Invoke(ref ctx, ref hargs); if (ctx.CheckForKick() || ctx.Result == HookResult.IGNORE) { return; } if (ctx.Result != HookResult.CONTINUE && !CheckAccessLevel(info, sender)) { sender.sendMessage("You cannot perform that action.", 255, 238, 130, 238); return; } try { info.Run(sender, hargs.ArgumentString); } catch (ExitException e) { throw e; } catch (CommandError e) { sender.sendMessage(prefix + ": " + e.Message); info.ShowHelp(sender); } return; } var args = new ArgumentList(); var command = Tokenize(line, args); if (command != null) { if (FindTokenCommand(command, out info)) { hargs.Arguments = args; foreach (BasePlugin plg in PluginManager.plugins.Values) { if (plg.commands.ContainsKey(command)) { args.Plugin = plg; } } HookPoints.Command.Invoke(ref ctx, ref hargs); if (ctx.CheckForKick() || ctx.Result == HookResult.IGNORE) { return; } if (ctx.Result != HookResult.CONTINUE && !CheckAccessLevel(info, sender)) { sender.sendMessage("You cannot perform that action.", 255, 238, 130, 238); return; } try { info.Run(sender, hargs.Arguments); } catch (ExitException e) { throw e; } catch (CommandError e) { sender.sendMessage(command + ": " + e.Message); info.ShowHelp(sender); } return; } else { sender.sendMessage("No such command."); } } } catch (ExitException e) { throw e; } catch (TokenizerException e) { sender.sendMessage(e.Message); } }
public bool Read(int bufferId, int start, int length) { var buffer = NetMessage.buffer[bufferId]; var player = Main.player[bufferId]; var conn = Netplay.Clients[bufferId]; if (Main.netMode != 2) { return(true); } var clientPassword = buffer.reader.ReadString(); if (conn.State == -1) { var ctx = new HookContext { Connection = conn.Socket, Player = player, Sender = player }; var args = new TDSMHookArgs.ServerPassReceived { Password = clientPassword, }; TDSMHookPoints.ServerPassReceived.Invoke(ref ctx, ref args); if (ctx.CheckForKick()) { return(true); } if (ctx.Result == HookResult.ASK_PASS) { NetMessage.SendData((int)Packet.PASSWORD_REQUEST, bufferId); return(true); } else if (ctx.Result == HookResult.CONTINUE || clientPassword == Netplay.ServerPassword) { Netplay.Clients[bufferId].State = 1; NetMessage.SendData((int)Packet.CONNECTION_RESPONSE, bufferId, -1, "", 0, 0f, 0f, 0f, 0, 0, 0); return(true); } conn.Kick("Incorrect server password."); } else if (conn.State == (int)ConnectionState.AwaitingUserPassword) { //var name = player.name ?? ""; var ctx = new HookContext { Connection = conn.Socket, Player = player, Sender = player }; var args = new TDSMHookArgs.PlayerPassReceived { Password = clientPassword }; TDSMHookPoints.PlayerPassReceived.Invoke(ref ctx, ref args); if (ctx.CheckForKick()) { return(true); } if (ctx.Result == HookResult.ASK_PASS) { NetMessage.SendData((int)Packet.PASSWORD_REQUEST, bufferId); return(true); } else // HookResult.DEFAULT { //ProgramLog.Error.Log("Accepted player: " + player.name + "/" + (player.AuthenticatedAs ?? "null")); //Continue with world request Netplay.Clients[bufferId].State = 2; Netplay.Clients[bufferId].ResetSections(); NetMessage.SendData(7, bufferId, -1, "", 0, 0f, 0f, 0f, 0, 0, 0); Main.SyncAnInvasion(bufferId); return(true); } } return(true); }
public override void Process(ClientConnection conn, byte[] readBuffer, int length, int num) { string chat; if (!ParseString(readBuffer, num + 4, length - 5, out chat)) { conn.Kick("Invalid characters in chat message."); return; } if (conn.State < SlotState.PLAYING) { if (chat != "/playing") { ProgramLog.Debug.Log("{0}: sent message PLAYER_CHAT in state {1}.", conn.RemoteAddress, conn.State); conn.Kick("Invalid operation at this state."); } else { ProgramLog.Debug.Log("Replying to early online player query."); var msg = NetMessage.PrepareThreadInstance(); msg.PlayerChat(255, string.Concat("Current players: ", String.Join(", ", from p in Main.players where p.Active select p.Name), "."), 255, 240, 20); conn.Send(msg.Output); } return; } int whoAmI = conn.SlotIndex; var player = Main.players[whoAmI]; if (chat.Length == 0) //TODO: check for undetectable spam { return; } if (chat.Substring(0, 1).Equals("/")) { if (Main.players[whoAmI].Op) { ProgramLog.Admin.Log(player.Name + " sent command: " + chat); } else { ProgramLog.Users.Log(player.Name + " sent command: " + chat); } Program.commandParser.ParsePlayerCommand(player, chat); return; } Color color = ChatColor.White; if (player.Op) { color = ChatColor.DeepSkyBlue; } else if (player.Difficulty == 1) { color = ChatColor.Khaki; } else if (player.Difficulty == 2) { color = ChatColor.Tomato; } else if (player.team > 0 && player.team < Main.teamColor.Length) { color = Main.teamColor[player.team]; } var ctx = new HookContext { Connection = player.Connection, Sender = player, Player = player, }; var args = new HookArgs.PlayerChat { Message = chat, Color = color, }; HookPoints.PlayerChat.Invoke(ref ctx, ref args); if (ctx.CheckForKick() || ctx.Result == HookResult.IGNORE) { return; } NetMessage.SendData(Packet.PLAYER_CHAT, -1, -1, chat, whoAmI, args.Color.R, args.Color.G, args.Color.B); ProgramLog.Chat.Log("<" + player.Name + "> " + chat, SendingLogger.PLAYER); }
public override void Process(int whoAmI, byte[] readBuffer, int length, int num) { byte action = ReadByte(readBuffer); int x = (int)ReadInt16(readBuffer); int y = (int)ReadInt16(readBuffer); short type = ReadInt16(readBuffer); int style = (int)ReadByte(readBuffer); bool fail = type == 1; var player = Main.player[whoAmI]; if (x < 0 || y < 0 || x >= Main.maxTilesX || y >= Main.maxTilesY) { player.Kick("Out of range tile received from client."); return; } if (!Terraria.Netplay.Clients[whoAmI].TileSections[Netplay.GetSectionX(x), Netplay.GetSectionY(y)]) { Tools.WriteLine("{0} @ {1}: {2} attempted to alter world in unloaded tile."); return; } //TODO implement the old methods var ctx = new HookContext { Connection = (Terraria.Netplay.Clients[whoAmI] as ServerSlot).conn, Sender = player, Player = player, }; var args = new HookArgs.PlayerWorldAlteration { X = x, Y = y, Action = action, Type = type, Style = style }; HookPoints.PlayerWorldAlteration.Invoke(ref ctx, ref args); if (ctx.CheckForKick()) { return; } if (ctx.Result == HookResult.IGNORE) { return; } if (ctx.Result == HookResult.RECTIFY) { //Terraria.WorldGen.SquareTileFrame (x, y, true); NewNetMessage.SendTileSquare(whoAmI, x, y, 1); return; } if (Main.tile[x, y] == null) { Main.tile[x, y] = new Tile(); } if (Main.netMode == 2) { if (!fail) { if (action == 0 || action == 2 || action == 4) { Terraria.Netplay.Clients[whoAmI].SpamDeleteBlock += 1f; } if (action == 1 || action == 3) { Terraria.Netplay.Clients[whoAmI].SpamAddBlock += 1f; } } if (!Terraria.Netplay.Clients[whoAmI].TileSections[Netplay.GetSectionX(x), Netplay.GetSectionY(y)]) { fail = true; } } if (action == 0) { WorldGen.KillTile(x, y, fail, false, false); } if (action == 1) { WorldGen.PlaceTile(x, y, (int)type, false, true, -1, style); } if (action == 2) { WorldGen.KillWall(x, y, fail); } if (action == 3) { WorldGen.PlaceWall(x, y, (int)type, false); } if (action == 4) { WorldGen.KillTile(x, y, fail, false, true); } if (action == 5) { WorldGen.PlaceWire(x, y); } if (action == 6) { WorldGen.KillWire(x, y); } if (action == 7) { WorldGen.PoundTile(x, y); } if (action == 8) { WorldGen.PlaceActuator(x, y); } if (action == 9) { WorldGen.KillActuator(x, y); } if (action == 10) { WorldGen.PlaceWire2(x, y); } if (action == 11) { WorldGen.KillWire2(x, y); } if (action == 12) { WorldGen.PlaceWire3(x, y); } if (action == 13) { WorldGen.KillWire3(x, y); } if (action == 14) { WorldGen.SlopeTile(x, y, (int)type); } if (action == 15) { Minecart.FrameTrack(x, y, true, false); } if (Main.netMode != 2) { return; } NewNetMessage.SendData(17, -1, whoAmI, String.Empty, (int)action, (float)x, (float)y, (float)type, style); if (action == 1 && type == 53) { NewNetMessage.SendTileSquare(-1, x, y, 1); return; } }
public override void Process(int whoAmI, byte[] readBuffer, int length, int num) { int x = BitConverter.ToInt32(readBuffer, num); num += 4; int y = BitConverter.ToInt32(readBuffer, num); num += 4; byte liquid = readBuffer[num++]; byte lavaFlag = readBuffer[num]++; var player = Main.players[whoAmI]; if (NetPlay.spamCheck) // dead code... { int centerX = (int)(player.Position.X + (float)(player.Width / 2)); int centerY = (int)(player.Position.Y + (float)(player.Height / 2)); int disperseDistance = 10; int left = centerX - disperseDistance; int right = centerX + disperseDistance; int top = centerY - disperseDistance; int bottom = centerY + disperseDistance; if (centerX < left || centerX > right || centerY < top || centerY > bottom) { NetMessage.BootPlayer(whoAmI, "Cheating attempt detected: Liquid spam"); return; } } var ctx = new HookContext { Connection = player.Connection, Player = player, Sender = player, }; var args = new HookArgs.LiquidFlowReceived { X = x, Y = y, Amount = liquid, Lava = lavaFlag == 1, }; HookPoints.LiquidFlowReceived.Invoke(ref ctx, ref args); if (ctx.CheckForKick()) { return; } if (ctx.Result == HookResult.IGNORE) { return; } if (ctx.Result == HookResult.RECTIFY) { var msg = NetMessage.PrepareThreadInstance(); msg.FlowLiquid(x, y); msg.Send(whoAmI); return; } TileRef tile = Main.tile.At(x, y); { tile.SetLiquid(liquid); tile.SetLava(lavaFlag == 1); WorldModify.SquareTileFrame(null, null, x, y, true); } }
public bool Read(int bufferId, int start, int length) { var buffer = NetMessage.buffer[bufferId]; ActionType action = (ActionType)buffer.reader.ReadByte(); int x = (int)buffer.reader.ReadInt16(); int y = (int)buffer.reader.ReadInt16(); short type = buffer.reader.ReadInt16(); int style = (int)buffer.reader.ReadByte(); bool fail = type == 1; if (!WorldGen.InWorld(x, y, 3)) { return(true); } var player = Main.player[bufferId]; //TODO implement the old methods var ctx = new HookContext { Connection = player.Connection.Socket, Sender = player, Player = player, }; var args = new TDSMHookArgs.PlayerWorldAlteration { X = x, Y = y, Action = action, Type = type, Style = style }; TDSMHookPoints.PlayerWorldAlteration.Invoke(ref ctx, ref args); if (ctx.CheckForKick()) { return(true); } if (ctx.Result == HookResult.IGNORE) { return(true); } if (ctx.Result == HookResult.RECTIFY) { //Terraria.WorldGen.SquareTileFrame (x, y, true); NetMessage.SendTileSquare(bufferId, x, y, 1); return(true); } if (Main.tile[x, y] == null) { Main.tile[x, y] = new OTA.Memory.MemTile(); } if (Main.netMode == 2) { if (!fail) { if (action == ActionType.KillTile || action == ActionType.KillWall || action == ActionType.KillTile1) { Netplay.Clients[bufferId].SpamDeleteBlock += 1; } if (action == ActionType.PlaceTile || action == ActionType.PlaceWall) { Netplay.Clients[bufferId].SpamAddBlock += 1; } } if (!Netplay.Clients[bufferId].TileSections[Netplay.GetSectionX(x), Netplay.GetSectionY(y)]) { fail = true; } } switch (action) { case ActionType.KillTile: WorldGen.KillTile(x, y, fail, false, false); break; case ActionType.PlaceTile: WorldGen.PlaceTile(x, y, (int)type, false, true, -1, style); break; case ActionType.KillWall: WorldGen.KillWall(x, y, fail); break; case ActionType.PlaceWall: WorldGen.PlaceWall(x, y, (int)type, false); break; case ActionType.KillTile1: WorldGen.KillTile(x, y, fail, false, true); break; case ActionType.PlaceWire: WorldGen.PlaceWall(x, y, (int)type, false); break; case ActionType.KillWire: WorldGen.KillWire(x, y); break; case ActionType.PoundTile: WorldGen.PoundTile(x, y); break; case ActionType.PlaceActuator: WorldGen.PlaceActuator(x, y); break; case ActionType.KillActuator: WorldGen.KillActuator(x, y); break; case ActionType.PlaceWire2: WorldGen.PlaceWire2(x, y); break; case ActionType.KillWire2: WorldGen.KillWire2(x, y); break; case ActionType.PlaceWire3: WorldGen.PlaceWire3(x, y); break; case ActionType.KillWire3: WorldGen.KillWire3(x, y); break; case ActionType.SlopeTile: WorldGen.SlopeTile(x, y, (int)type); break; case ActionType.FrameTrack: Minecart.FrameTrack(x, y, true, false); break; case ActionType.PlaceWire4: WorldGen.PlaceWire4(x, y); break; case ActionType.KillWire4: WorldGen.KillWire4(x, y); break; case ActionType.PlaceLogicGate: Wiring.SetCurrentUser(bufferId); Wiring.PokeLogicGate(x, y); Wiring.SetCurrentUser(-1); return(true); case ActionType.Actuate: Wiring.SetCurrentUser(bufferId); Wiring.Actuate(x, y); Wiring.SetCurrentUser(-1); return(true); } if (Main.netMode != 2) { return(true); } NetMessage.SendData(17, -1, bufferId, "", (int)action, (float)x, (float)y, (float)type, style, 0, 0); if (action == ActionType.PlaceTile && type == 53) { NetMessage.SendTileSquare(-1, x, y, 1); } return(true); }