PageRenderTime 93ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 1ms

/Player/Player.cs

https://github.com/Goodlyay/MCForge-Vanilla-Redux
C# | 5648 lines | 4925 code | 407 blank | 316 comment | 1441 complexity | e0ca8114698deb71d5b5de7aa8017194 MD5 | raw file
  1. /*
  2. Copyright 2010 MCSharp team (Modified for use with MCZall/MCLawl/MCForge)
  3. Dual-licensed under the Educational Community License, Version 2.0 and
  4. the GNU General Public License, Version 3 (the "Licenses"); you may
  5. not use this file except in compliance with the Licenses. You may
  6. obtain a copy of the Licenses at
  7. http://www.opensource.org/licenses/ecl2.php
  8. http://www.gnu.org/licenses/gpl-3.0.html
  9. Unless required by applicable law or agreed to in writing,
  10. software distributed under the Licenses are distributed on an "AS IS"
  11. BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
  12. or implied. See the Licenses for the specific language governing
  13. permissions and limitations under the Licenses.
  14. */
  15. using System;
  16. using System.Collections.Generic;
  17. using System.Data;
  18. using System.Globalization;
  19. using System.IO;
  20. using System.Linq;
  21. using System.Net;
  22. using System.Net.Sockets;
  23. using System.Security.Cryptography;
  24. using System.Text;
  25. using System.Text.RegularExpressions;
  26. using System.Threading;
  27. using Newtonsoft.Json.Linq;
  28. using MCForge.SQL;
  29. namespace MCForge
  30. {
  31. public sealed partial class Player : IDisposable
  32. {
  33. public void ClearChat() { OnChat = null; }
  34. /// <summary>
  35. /// List of all server players.
  36. /// </summary>
  37. public static List<Player> players = new List<Player>();
  38. /// <summary>
  39. /// Key - Name
  40. /// Value - IP
  41. /// All players who have left this restart.
  42. /// </summary>
  43. public static Dictionary<string, string> left = new Dictionary<string, string>();
  44. /// <summary>
  45. ///
  46. /// </summary>
  47. public static List<Player> connections = new List<Player>(Server.players);
  48. System.Timers.Timer muteTimer = new System.Timers.Timer(1000);
  49. public static List<string> emoteList = new List<string>();
  50. public List<string> listignored = new List<string>();
  51. public List<string> mapgroups = new List<string>();
  52. public static List<string> globalignores = new List<string>();
  53. public static int totalMySQLFailed = 0;
  54. public static byte number { get { return (byte)players.Count; } }
  55. static System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
  56. static MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
  57. public static string lastMSG = "";
  58. public static bool storeHelp = false;
  59. public static string storedHelp = "";
  60. private string truename;
  61. internal bool dontmindme = false;
  62. public Socket socket;
  63. System.Timers.Timer timespent = new System.Timers.Timer(1000);
  64. System.Timers.Timer loginTimer = new System.Timers.Timer(1000);
  65. public System.Timers.Timer pingTimer = new System.Timers.Timer(2000);
  66. System.Timers.Timer extraTimer = new System.Timers.Timer(22000);
  67. public System.Timers.Timer afkTimer = new System.Timers.Timer(2000);
  68. public int afkCount = 0;
  69. public DateTime afkStart;
  70. public string WoMVersion = "";
  71. public bool megaBoid = false;
  72. public bool cmdTimer = false;
  73. public bool UsingWom = false;
  74. byte[] buffer = new byte[0];
  75. byte[] tempbuffer = new byte[0xFF];
  76. public bool disconnected = false;
  77. public string time;
  78. public string name;
  79. public bool identified = false;
  80. public bool UsingID = false;
  81. public int ID = 0;
  82. public int warn = 0;
  83. public byte id;
  84. public int userID = -1;
  85. public string ip;
  86. public string exIP; // external IP
  87. public string color;
  88. public Group group;
  89. public bool hidden = false;
  90. public bool painting = false;
  91. public bool muted = false;
  92. public bool jailed = false;
  93. public bool agreed = false;
  94. public bool invincible = false;
  95. public string prefix = "";
  96. public string title = "";
  97. public string titlecolor;
  98. public int TotalMessagesSent = 0;
  99. public int passtries = 0;
  100. public int ponycount = 0;
  101. public int rdcount = 0;
  102. public bool hasreadrules = false;
  103. public bool canusereview = true;
  104. //Gc checks
  105. public string lastmsg = "";
  106. public int spamcount = 0, capscount = 0, floodcount = 0, multi = 0;
  107. public DateTime lastmsgtime = DateTime.MinValue;
  108. /// <summary>
  109. /// Console only please
  110. /// </summary>
  111. public bool canusegc = true;
  112. //Pyramid Code
  113. public int pyramidx1;
  114. public int pyramidx2;
  115. public int pyramidy1;
  116. public int pyramidy2;
  117. public int pyramidz1;
  118. public int pyramidz2;
  119. public string pyramidblock;
  120. public int pyramidtotal;
  121. public int pyramidtotal2;
  122. public bool pyramidsilent = false;
  123. public bool deleteMode = false;
  124. public bool ignorePermission = false;
  125. public bool ignoreGrief = false;
  126. public bool parseSmiley = true;
  127. public bool smileySaved = true;
  128. public bool opchat = false;
  129. public bool adminchat = false;
  130. public bool onWhitelist = false;
  131. public bool whisper = false;
  132. public string whisperTo = "";
  133. public bool ignoreglobal = false;
  134. public string storedMessage = "";
  135. public bool trainGrab = false;
  136. public bool onTrain = false;
  137. public bool allowTnt = true;
  138. public bool frozen = false;
  139. public string following = "";
  140. public string possess = "";
  141. // Only used for possession.
  142. //Using for anything else can cause unintended effects!
  143. public bool canBuild = true;
  144. public int money = 0;
  145. public long overallBlocks = 0;
  146. public int loginBlocks = 0;
  147. public DateTime timeLogged;
  148. public DateTime firstLogin;
  149. public int totalLogins = 0;
  150. public int totalKicked = 0;
  151. public int overallDeath = 0;
  152. public string savedcolor = "";
  153. public bool staticCommands = false;
  154. public DateTime ZoneSpam;
  155. public bool ZoneCheck = false;
  156. public bool zoneDel = false;
  157. public Thread commThread;
  158. public bool commUse = false;
  159. public bool aiming;
  160. public bool isFlying = false;
  161. public bool joker = false;
  162. public bool adminpen = false;
  163. public bool voice = false;
  164. public string voicestring = "";
  165. public int grieferStoneWarn = 0;
  166. // CTF
  167. public CTFTeam team;
  168. public bool carryingFlag;
  169. public bool justDroppedFlag = false;
  170. public CatchPos placedTNT;
  171. public CatchPos placedMine;
  172. public int captureStreak;
  173. public int captureCount;
  174. public int kills;
  175. public int deaths;
  176. public int drownCount;
  177. public int totalCaptures;
  178. public int totalKills;
  179. public int totalDeaths;
  180. public int totalReturns;
  181. bool isActivating;
  182. public struct CatchPos
  183. {
  184. public ushort x, y, z;
  185. public bool isActive;
  186. }
  187. public List<string> playersKilled = new List<string>();
  188. public int getKillCount(string name)
  189. {
  190. int count = 0;
  191. playersKilled.ForEach(delegate(string kill)
  192. {
  193. if (name.ToLower() == kill.ToLower())
  194. {
  195. count++;
  196. }
  197. });
  198. return count;
  199. }
  200. public void Reward(int reward)
  201. {
  202. money += reward;
  203. }
  204. public void killPlayer(Player killed)
  205. {
  206. playersKilled.Add(killed.name);
  207. killed.deaths++;
  208. kills++;
  209. Reward(CTF.killPlayerReward);
  210. if (getKillCount(killed.name) % 5 == 0)
  211. {
  212. Player.GlobalMessage("&f- " + color + name + "&b is dominating " + killed.color + killed.name + "&b!");
  213. }
  214. if (killed.carryingFlag)
  215. {
  216. Command.all.Find("drop").Use(killed, "");
  217. }
  218. killed.team.SpawnPlayer(killed);
  219. }
  220. //Countdown
  221. public bool playerofcountdown = false;
  222. public bool incountdown = false;
  223. public ushort countdowntempx;
  224. public ushort countdowntempz;
  225. public bool countdownsettemps = false;
  226. //Zombie
  227. public string Original = "";
  228. public bool referee = false;
  229. public int blockCount = 50;
  230. public bool voted = false;
  231. public int blocksStacked = 0;
  232. public int infectThisRound = 0;
  233. public int lastYblock = 0;
  234. public int lastXblock = 0;
  235. public int lastZblock = 0;
  236. public bool infected = false;
  237. public bool aka = false;
  238. public bool flipHead = true;
  239. public int playersInfected = 0;
  240. public int NoClipcount = 0;
  241. //SMP Mode
  242. public bool InSMP = false;
  243. public uint rock = (uint)0;
  244. public uint grass = (uint)0;
  245. public uint dirt = (uint)0;
  246. public uint stone = (uint)0;
  247. public uint wood = (uint)0;
  248. public uint shrub = (uint)0;
  249. public uint blackrock = (uint)0;// adminium
  250. public uint water = (uint)0;
  251. public uint waterstill = (uint)0;
  252. public uint lava = (uint)0;
  253. public uint lavastill = (uint)0;
  254. public uint sand = (uint)0;
  255. public uint gravel = (uint)0;
  256. public uint goldrock = (uint)0;
  257. public uint ironrock = (uint)0;
  258. public uint coal = (uint)0;
  259. public uint trunk = (uint)0;
  260. public uint leaf = (uint)0;
  261. public uint sponge = (uint)0;
  262. public uint glass = (uint)0;
  263. public uint red = (uint)0;
  264. public uint orange = (uint)0;
  265. public uint yellow = (uint)0;
  266. public uint lightgreen = (uint)0;
  267. public uint green = (uint)0;
  268. public uint aquagreen = (uint)0;
  269. public uint cyan = (uint)0;
  270. public uint lightblue = (uint)0;
  271. public uint blue = (uint)0;
  272. public uint purple = (uint)0;
  273. public uint lightpurple = (uint)0;
  274. public uint pink = (uint)0;
  275. public uint darkpink = (uint)0;
  276. public uint darkgrey = (uint)0;
  277. public uint lightgrey = (uint)0;
  278. public uint white = (uint)0;
  279. public uint yellowflower = (uint)0;
  280. public uint redflower = (uint)0;
  281. public uint mushroom = (uint)0;
  282. public uint redmushroom = (uint)0;
  283. public uint goldsolid = (uint)0;
  284. public uint iron = (uint)0;
  285. public uint staircasefull = (uint)0;
  286. public uint staircasestep = (uint)0;
  287. public uint brick = (uint)0;
  288. public uint tnt = (uint)0;
  289. public uint bookcase = (uint)0;
  290. public uint stonevine = (uint)0;
  291. public uint obsidian = (uint)0;
  292. public uint cobblestoneslab = (uint)0;
  293. public uint rope = (uint)0;
  294. public uint sandstone = (uint)0;
  295. public uint snowreal = (uint)0;
  296. public uint firereal = (uint)0;
  297. public uint lightpinkwool = (uint)0;
  298. public uint forestgreenwool = (uint)0;
  299. public uint brownwool = (uint)0;
  300. public uint deepblue = (uint)0;
  301. public uint turquoise = (uint)0;
  302. public uint ice = (uint)0;
  303. public uint ceramictile = (uint)0;
  304. public uint magmablock = (uint)0;
  305. public uint pillar = (uint)0;
  306. public uint crate = (uint)0;
  307. public uint stonebrick = (uint)0;
  308. //Tnt Wars
  309. public bool PlayingTntWars = false;
  310. public int CurrentAmountOfTnt = 0;
  311. public int CurrentTntGameNumber; //For keeping track of which game is which
  312. public int TntWarsHealth = 2;
  313. public int TntWarsKillStreak = 0;
  314. public float TntWarsScoreMultiplier = 1f;
  315. public int TNTWarsLastKillStreakAnnounced = 0;
  316. public bool inTNTwarsMap = false;
  317. public Player HarmedBy = null; //For Assists
  318. //Copy
  319. public List<CopyPos> CopyBuffer = new List<CopyPos>();
  320. public struct CopyPos { public ushort x, y, z; public ushort type; }
  321. public bool copyAir = false;
  322. public int[] copyoffset = new int[3] { 0, 0, 0 };
  323. public ushort[] copystart = new ushort[3] { 0, 0, 0 };
  324. public bool Mojangaccount
  325. {
  326. get
  327. {
  328. return truename.Contains('@');
  329. }
  330. }
  331. //Undo
  332. public struct UndoPos { public ushort x, y, z; public ushort type, newtype; public string mapName; public DateTime timePlaced; }
  333. public List<UndoPos> UndoBuffer = new List<UndoPos>();
  334. public List<UndoPos> RedoBuffer = new List<UndoPos>();
  335. public bool showPortals = false;
  336. public bool showMBs = false;
  337. public string prevMsg = "";
  338. //Block Change variable holding
  339. public int[] BcVar;
  340. //Movement
  341. public ushort oldBlock = 0;
  342. public ushort deathCount = 0;
  343. public ushort deathblock;
  344. //Games
  345. public DateTime lastDeath = DateTime.Now;
  346. public byte blockAction; //0-Nothing 1-solid 2-lava 3-water 4-active_lava 5 Active_water 6 OpGlass 7 BluePort 8 OrangePort
  347. public ushort modeType;
  348. public ushort[] bindings = new ushort[(ushort)128];
  349. public string[] cmdBind = new string[10];
  350. public string[] messageBind = new string[10];
  351. public string lastCMD = "";
  352. public sbyte c4circuitNumber = -1;
  353. public Level level = Server.mainLevel;
  354. public bool Loading = true; //True if player is loading a map.
  355. public ushort[] lastClick = new ushort[] { 0, 0, 0 };
  356. public ushort[] pos = new ushort[] { 0, 0, 0 };
  357. ushort[] oldpos = new ushort[] { 0, 0, 0 };
  358. // ushort[] basepos = new ushort[] { 0, 0, 0 };
  359. public byte[] rot = new byte[] { 0, 0 };
  360. byte[] oldrot = new byte[] { 0, 0 };
  361. //ushort[] clippos = new ushort[3] { 0, 0, 0 };
  362. //byte[] cliprot = new byte[2] { 0, 0 };
  363. // grief/spam detection
  364. public static int spamBlockCount = 200;
  365. public bool isUsingOpenClassic = false;
  366. public static int spamBlockTimer = 5;
  367. Queue<DateTime> spamBlockLog = new Queue<DateTime>(spamBlockCount);
  368. public int consecutivemessages;
  369. private System.Timers.Timer resetSpamCount = new System.Timers.Timer(Server.spamcountreset * 1000);
  370. //public static int spamChatCount = 3;
  371. //public static int spamChatTimer = 4;
  372. //Queue<DateTime> spamChatLog = new Queue<DateTime>(spamChatCount);
  373. // CmdVoteKick
  374. public VoteKickChoice voteKickChoice = VoteKickChoice.HasntVoted;
  375. // Extra storage for custom commands
  376. public ExtrasCollection Extras = new ExtrasCollection();
  377. //Chatrooms
  378. public string Chatroom;
  379. public List<string> spyChatRooms = new List<string>();
  380. public DateTime lastchatroomglobal;
  381. //Waypoints
  382. public List<Waypoint.WP> Waypoints = new List<Waypoint.WP>();
  383. //Random...
  384. public Random random = new Random();
  385. //Global Chat
  386. public bool muteGlobal;
  387. public bool loggedIn;
  388. public bool InGlobalChat { get; set; }
  389. public Dictionary<string, string> sounds = new Dictionary<string, string>();
  390. public bool isDev, isMod, isGCMod; //is this player a dev/mod/gcmod?
  391. public bool isStaff;
  392. public bool isProtected;
  393. public bool verifiedName;
  394. //CPE
  395. const string SelectionBoxExtName = "SelectionBoxExt";
  396. const int SelectionBoxExtVersion = 1;
  397. const string CustomBlocksExtName = "CustomBlocks";
  398. const int CustomBlocksExtVersion = 1;
  399. const byte CustomBlocksLevel = 1;
  400. const string ClickDistanceExtName = "ClickDistance";
  401. const int ClickDistanceExtVersion = 1;
  402. const string EnvColorsExtName = "EnvColors";
  403. const int EnvColorsExtVersion = 1;
  404. const string ChangeModelExtName = "ChangeModel";
  405. const int ChangeModelExtVersion = 1;
  406. const string EnvMapAppearanceExtName = "EnvMapAppearance";
  407. const int EnvMapAppearanceExtVersion = 1;
  408. const string HeldBlockExtName = "HeldBlock";
  409. const int HeldBlockExtVersion = 1;
  410. const string ExtPlayerListExtName = "ExtPlayerList";
  411. const int ExtPlayerListExtVersion = 1;
  412. const string SelectionCuboidExtName = "SelectionCuboid";
  413. const int SelectionCuboidExtVersion = 1;
  414. const string MessageTypesExtName = "MessageTypes";
  415. const int MessageTypesExtVersion = 1;
  416. const string EnvWeatherTypeExtName = "EnvWeatherType";
  417. const int EnvWeatherTypeExtVersion = 1;
  418. const string HackControlExtName = "HackControl";
  419. const int HackControlExtVersion = 1;
  420. // Note: if more levels are added, change UsesCustomBlocks from bool to int
  421. public bool SelectionBoxExt { get; set; }
  422. public bool UsesCustomBlocks { get; set; }
  423. public bool SupportsClickDistance = false;
  424. public bool SupportsEnvColors = false;
  425. public bool SupportsChangeModel = false;
  426. public bool SupportsEnvMapAppearance = false;
  427. public bool SupportsEnvWeatherType = false;
  428. public bool SupportsHeldBlock = false;
  429. public bool SupportsExtPlayerList = false;
  430. public bool SupportsSelectionCuboid = false;
  431. public bool SupportsMessageTypes = false;
  432. public bool SupportsHackControl = false;
  433. public static bool emotefix = false;
  434. public string appName;
  435. public int extensionCount;
  436. public List<string> extensions = new List<string>();
  437. public int customBlockSupportLevel;
  438. public bool extension;
  439. public struct OfflinePlayer
  440. {
  441. public string name, color, title, titleColor;
  442. public int money;
  443. //need moar? add moar! just make sure you adjust Player.FindOffline() method
  444. /// <summary>
  445. /// Creates a new OfflinePlayer object.
  446. /// </summary>
  447. /// <param name="nm">Name of the player.</param>
  448. /// <param name="clr">Color of player name.</param>
  449. /// <param name="tl">Title of player.</param>
  450. /// <param name="tlclr">Title color of player</param>
  451. /// <param name="mon">Player's money.</param>
  452. public OfflinePlayer(string nm, string clr, string tl, string tlclr, int mon) { name = nm; color = clr; title = tl; titleColor = tlclr; money = mon; }
  453. }
  454. public static string CheckPlayerStatus(Player p)
  455. {
  456. if (p.hidden)
  457. return "hidden";
  458. if (Server.afkset.Contains(p.name))
  459. return "afk";
  460. return "active";
  461. }
  462. public bool Readgcrules = false;
  463. public DateTime Timereadgcrules = DateTime.MinValue;
  464. public bool CheckIfInsideBlock()
  465. {
  466. return CheckIfInsideBlock(this);
  467. }
  468. public static bool CheckIfInsideBlock(Player p)
  469. {
  470. ushort x, y, z;
  471. x = (ushort)(p.pos[0] / 32);
  472. y = (ushort)(p.pos[1] / 32);
  473. y = (ushort)Math.Round((decimal)(((y * 32) + 4) / 32));
  474. z = (ushort)(p.pos[2] / 32);
  475. ushort b = p.level.GetTile(x, y, z);
  476. ushort b1 = p.level.GetTile(x, (ushort)(y - 1), z);
  477. if (Block.Walkthrough(Block.Convert(b)) && Block.Walkthrough(Block.Convert(b1)))
  478. {
  479. return false;
  480. }
  481. return Block.Convert(b) != Block.Zero && Block.Convert(b) != Block.op_air;
  482. }
  483. //This is so that plugin devs can declare a player without needing a socket..
  484. //They would still have to do p.Dispose()..
  485. public Player(string playername) { name = playername; }
  486. public Queue<Packet> Packets;
  487. public NetworkStream Stream;
  488. public BinaryReader Reader;
  489. public Player(Socket s)
  490. {
  491. try
  492. {
  493. socket = s;
  494. ip = socket.RemoteEndPoint.ToString().Split(':')[0];
  495. if (IPInPrivateRange(ip))
  496. exIP = ResolveExternalIP(ip);
  497. else
  498. exIP = ip;
  499. Server.s.Log(ip + " connected to the server.");
  500. for (byte i = 0; i < 128; ++i) bindings[i] = i;
  501. socket.BeginReceive(tempbuffer, 0, tempbuffer.Length, SocketFlags.None, new AsyncCallback(Receive), this);
  502. timespent.Elapsed += delegate
  503. {
  504. if (!Loading)
  505. {
  506. try
  507. {
  508. int Days = Convert.ToInt32(time.Split(' ')[0]);
  509. int Hours = Convert.ToInt32(time.Split(' ')[1]);
  510. int Minutes = Convert.ToInt32(time.Split(' ')[2]);
  511. int Seconds = Convert.ToInt32(time.Split(' ')[3]);
  512. Seconds++;
  513. if (Seconds >= 60)
  514. {
  515. Minutes++;
  516. Seconds = 0;
  517. }
  518. if (Minutes >= 60)
  519. {
  520. Hours++;
  521. Minutes = 0;
  522. }
  523. if (Hours >= 24)
  524. {
  525. Days++;
  526. Hours = 0;
  527. }
  528. time = "" + Days + " " + Hours + " " + Minutes + " " + Seconds;
  529. }
  530. catch { time = "0 0 0 1"; }
  531. }
  532. };
  533. timespent.Start();
  534. loginTimer.Elapsed += delegate
  535. {
  536. if (!Loading)
  537. {
  538. loginTimer.Stop();
  539. if (File.Exists("text/welcome.txt"))
  540. {
  541. try
  542. {
  543. using (StreamReader wm = File.OpenText("text/welcome.txt"))
  544. {
  545. List<string> welcome = new List<string>();
  546. while (!wm.EndOfStream)
  547. welcome.Add(wm.ReadLine());
  548. foreach (string w in welcome)
  549. SendMessage(w);
  550. }
  551. }
  552. catch { }
  553. }
  554. else
  555. {
  556. Server.s.Log("Could not find welcome.txt. Using default.");
  557. File.WriteAllText("text/welcome.txt", "Welcome to my server!");
  558. SendMessage("Welcome to my server!");
  559. }
  560. extraTimer.Start();
  561. loginTimer.Dispose();
  562. }
  563. }; loginTimer.Start();
  564. pingTimer.Elapsed += delegate { SendPing(); };
  565. pingTimer.Start();
  566. extraTimer.Elapsed += delegate
  567. {
  568. extraTimer.Stop();
  569. try
  570. {
  571. if (!Group.Find("Nobody").commands.Contains("inbox") && !Group.Find("Nobody").commands.Contains("send"))
  572. {
  573. //safe against SQL injections because no user input is given here
  574. DataTable Inbox = Database.fillData("SELECT * FROM `Inbox" + name + "`", true);
  575. SendMessage("&cYou have &f" + Inbox.Rows.Count + Server.DefaultColor + " &cmessages in /inbox");
  576. Inbox.Dispose();
  577. }
  578. }
  579. catch { }
  580. if (Server.updateTimer.Interval > 1000) SendMessage("Lowlag mode is currently &aON.");
  581. try
  582. {
  583. if (!Group.Find("Nobody").commands.Contains("pay") && !Group.Find("Nobody").commands.Contains("give") && !Group.Find("Nobody").commands.Contains("take")) SendMessage("You currently have &a" + money + Server.DefaultColor + " " + Server.moneys);
  584. }
  585. catch { }
  586. SendMessage("You have modified &a" + overallBlocks + Server.DefaultColor + " blocks!");
  587. if (players.Count == 1)
  588. SendMessage("There is currently &a" + players.Count + " player online.");
  589. else
  590. SendMessage("There are currently &a" + players.Count + " players online.");
  591. try
  592. {
  593. if (!Group.Find("Nobody").commands.Contains("award") && !Group.Find("Nobody").commands.Contains("awards") && !Group.Find("Nobody").commands.Contains("awardmod")) SendMessage("You have " + Awards.awardAmount(name) + " awards.");
  594. }
  595. catch { }
  596. try
  597. {
  598. ZombieGame.alive.Remove(this);
  599. ZombieGame.infectd.Remove(this);
  600. }
  601. catch { }
  602. if (Server.lava.active) SendMessage("There is a &aLava Survival " + Server.DefaultColor + "game active! Join it by typing /ls go");
  603. extraTimer.Dispose();
  604. };
  605. afkTimer.Elapsed += delegate
  606. {
  607. if (name == "") return;
  608. if (Server.afkset.Contains(name))
  609. {
  610. afkCount = 0;
  611. if (Server.afkkick > 0 && group.Permission < Server.afkkickperm)
  612. if (afkStart.AddMinutes(Server.afkkick) < DateTime.Now)
  613. Kick("Auto-kick, AFK for " + Server.afkkick + " minutes");
  614. if ((oldpos[0] != pos[0] || oldpos[1] != pos[1] || oldpos[2] != pos[2]) && (oldrot[0] != rot[0] || oldrot[1] != rot[1]))
  615. Command.all.Find("afk").Use(this, "");
  616. }
  617. else
  618. {
  619. if (oldpos[0] == pos[0] && oldpos[1] == pos[1] && oldpos[2] == pos[2] && oldrot[0] == rot[0] && oldrot[1] == rot[1])
  620. afkCount++;
  621. else
  622. afkCount = 0;
  623. if (afkCount > Server.afkminutes * 30)
  624. {
  625. if (name != null && !String.IsNullOrEmpty(name.Trim()))
  626. {
  627. Command.all.Find("afk").Use(this, "auto: Not moved for " + Server.afkminutes + " minutes");
  628. if (AFK != null)
  629. AFK(this);
  630. if (ONAFK != null)
  631. ONAFK(this);
  632. OnPlayerAFKEvent.Call(this);
  633. afkCount = 0;
  634. }
  635. }
  636. }
  637. };
  638. resetSpamCount.Elapsed += delegate
  639. {
  640. if (consecutivemessages > 0)
  641. consecutivemessages = 0;
  642. };
  643. resetSpamCount.Start();
  644. if (Server.afkminutes > 0) afkTimer.Start();
  645. connections.Add(this);
  646. }
  647. catch (Exception e) { Kick("Login failed!"); Server.ErrorLog(e); }
  648. }
  649. public bool HasExtension (string extName)
  650. {
  651. return ExtEntry.FindAll (cpe => cpe.name == extName) != null;
  652. }
  653. public void save()
  654. {
  655. //safe against SQL injects because no user input is provided
  656. string commandString =
  657. "UPDATE Players SET IP='" + ip + "'" +
  658. ", LastLogin='" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "'" +
  659. ", totalLogin=" + totalLogins +
  660. ", totalDeaths=" + overallDeath +
  661. ", Money=" + money +
  662. ", totalBlocks=" + overallBlocks + " + " + loginBlocks +
  663. ", totalKicked=" + totalKicked +
  664. ", TimeSpent='" + time +
  665. "' WHERE Name='" + name + "'";
  666. if (MySQLSave != null)
  667. MySQLSave(this, commandString);
  668. OnMySQLSaveEvent.Call(this, commandString);
  669. if (cancelmysql)
  670. {
  671. cancelmysql = false;
  672. return;
  673. }
  674. if (!Server.useMySQL)
  675. SQLite.executeQuery(commandString);
  676. else
  677. MySQL.executeQuery(commandString);
  678. try
  679. {
  680. if (!smileySaved)
  681. {
  682. if (parseSmiley)
  683. emoteList.RemoveAll(s => s == name);
  684. else
  685. emoteList.Add(name);
  686. File.WriteAllLines("text/emotelist.txt", emoteList.ToArray());
  687. smileySaved = true;
  688. }
  689. }
  690. catch (Exception e)
  691. {
  692. Server.ErrorLog(e);
  693. }
  694. try
  695. {
  696. SaveUndo();
  697. }
  698. catch (Exception e)
  699. {
  700. Server.s.Log("Error saving undo data.");
  701. Server.ErrorLog(e);
  702. }
  703. }
  704. #region == INCOMING ==
  705. static void Receive(IAsyncResult result)
  706. {
  707. //Server.s.Log(result.AsyncState.ToString());
  708. Player p = (Player)result.AsyncState;
  709. if (p.disconnected || p.socket == null)
  710. return;
  711. try
  712. {
  713. int length = p.socket.EndReceive(result);
  714. if (length == 0) { p.Disconnect(); return; }
  715. byte[] b = new byte[p.buffer.Length + length];
  716. Buffer.BlockCopy(p.buffer, 0, b, 0, p.buffer.Length);
  717. Buffer.BlockCopy(p.tempbuffer, 0, b, p.buffer.Length, length);
  718. p.buffer = p.HandleMessage(b);
  719. if (p.dontmindme && p.buffer.Length == 0)
  720. {
  721. Server.s.Log("Disconnected");
  722. p.socket.Close();
  723. p.disconnected = true;
  724. return;
  725. }
  726. if (!p.disconnected)
  727. p.socket.BeginReceive(p.tempbuffer, 0, p.tempbuffer.Length, SocketFlags.None,
  728. new AsyncCallback(Receive), p);
  729. }
  730. catch (SocketException)
  731. {
  732. p.Disconnect();
  733. }
  734. catch (ObjectDisposedException)
  735. {
  736. // Player is no longer connected, socket was closed
  737. // Mark this as disconnected and remove them from active connection list
  738. Player.SaveUndo(p);
  739. if (connections.Contains(p))
  740. connections.Remove(p);
  741. p.disconnected = true;
  742. }
  743. catch (Exception e)
  744. {
  745. Server.ErrorLog(e);
  746. p.Kick("Error!");
  747. }
  748. }
  749. byte[] HandleMessage(byte[] buffer)
  750. {
  751. try
  752. {
  753. int length = 0; byte msg = buffer[0];
  754. // Get the length of the message by checking the first byte
  755. switch (msg)
  756. {
  757. //For wom
  758. case (byte)'G':
  759. level.textures.ServeCfg(this, buffer);
  760. return new byte[1];
  761. case 0:
  762. length = 130;
  763. break; // login
  764. case 5:
  765. if (!loggedIn)
  766. goto default;
  767. length = 8;
  768. break; // blockchange
  769. case 8:
  770. if (!loggedIn)
  771. goto default;
  772. length = 9;
  773. break; // input
  774. case 13:
  775. if (!loggedIn)
  776. goto default;
  777. length = 65;
  778. break; // chat
  779. case 16:
  780. length = 66;
  781. break;
  782. case 17:
  783. length = 68;
  784. break;
  785. case 19:
  786. length = 1;
  787. break;
  788. default:
  789. if (!dontmindme)
  790. Kick("Unhandled message id \"" + msg + "\"!");
  791. else
  792. Server.s.Log(Encoding.UTF8.GetString(buffer, 0, buffer.Length));
  793. return new byte[0];
  794. }
  795. if (buffer.Length > length)
  796. {
  797. byte[] message = new byte[length];
  798. Buffer.BlockCopy(buffer, 1, message, 0, length);
  799. byte[] tempbuffer = new byte[buffer.Length - length - 1];
  800. Buffer.BlockCopy(buffer, length + 1, tempbuffer, 0, buffer.Length - length - 1);
  801. buffer = tempbuffer;
  802. // Thread thread = null;
  803. switch (msg)
  804. {
  805. case 0:
  806. HandleLogin(message);
  807. break;
  808. case 5:
  809. if (!loggedIn)
  810. break;
  811. HandleBlockchange(message);
  812. break;
  813. case 8:
  814. if (!loggedIn)
  815. break;
  816. HandleInput(message);
  817. break;
  818. case 13:
  819. if (!loggedIn)
  820. break;
  821. HandleChat(message);
  822. break;
  823. case 16:
  824. HandleExtInfo(message);
  825. break;
  826. case 17:
  827. HandleExtEntry(message);
  828. break;
  829. case 19:
  830. HandleCustomBlockSupportLevel(message);
  831. break;
  832. }
  833. //thread.Start((object)message);
  834. if (buffer.Length > 0)
  835. buffer = HandleMessage(buffer);
  836. else
  837. return new byte[0];
  838. }
  839. }
  840. catch (Exception e)
  841. {
  842. Server.ErrorLog(e);
  843. }
  844. return buffer;
  845. }
  846. public void HandleExtInfo(byte[] message)
  847. {
  848. appName = enc.GetString(message, 0, 64).Trim();
  849. extensionCount = message[65];
  850. }
  851. public struct CPE { public string name; public int version; }
  852. public List<CPE> ExtEntry = new List<CPE>();
  853. void HandleExtEntry(byte[] msg)
  854. {
  855. CPE tmp; tmp.name = enc.GetString(msg, 0, 64);
  856. tmp.version = BitConverter.ToInt32(msg, 64);
  857. ExtEntry.Add(tmp);
  858. }
  859. public void HandleCustomBlockSupportLevel(byte[] message)
  860. {
  861. customBlockSupportLevel = message[0];
  862. }
  863. void HandleLogin(byte[] message)
  864. {
  865. try
  866. {
  867. //byte[] message = (byte[])m;
  868. if (loggedIn)
  869. return;
  870. byte version = message[0];
  871. name = enc.GetString(message, 1, 64).Trim();
  872. truename = name;
  873. if (Server.omniban.CheckPlayer(this)) { Kick(Server.omniban.kickMsg); return; } //deprecated
  874. if (name.Split('@').Length > 1)
  875. {
  876. name = name.Split('@')[0];
  877. if (!MojangAccount.HasID(truename))
  878. MojangAccount.AddUser(truename);
  879. name += "_" + MojangAccount.GetID(truename);
  880. }
  881. string verify = enc.GetString(message, 65, 32).Trim();
  882. ushort type = message[129];
  883. //Forge Protection Check
  884. verifiedName = Server.verify ? true : false;
  885. if (Server.verify)
  886. {
  887. if (verify == BitConverter.ToString(md5.ComputeHash(enc.GetBytes(Server.salt + truename))).Replace("-", "").ToLower().TrimStart('0'))
  888. {
  889. identified = true;
  890. }
  891. if (verify == BitConverter.ToString(md5.ComputeHash(enc.GetBytes(Server.salt2 + truename))).Replace("-", "").ToLower())
  892. {
  893. JObject json;
  894. try
  895. {
  896. using (var client = new WebClient())
  897. {
  898. json = JObject.Parse(client.DownloadString("http://www.classicube.net/api/player/" + name.ToLower()));
  899. }
  900. ID = (int)json.SelectToken("id");
  901. UsingID = true;
  902. }
  903. catch (Exception e)
  904. {
  905. Server.ErrorLog(e);
  906. Server.s.Log("Could not get Player's ID, going with name bans!");
  907. UsingID = false;
  908. }
  909. identified = true;
  910. name += "+";
  911. }
  912. if (IPInPrivateRange(ip))
  913. {
  914. identified = true;
  915. }
  916. if (identified == false)
  917. {
  918. Kick("Login failed! Try again."); return;
  919. }
  920. isDev = Server.Devs.Contains(name.ToLower());
  921. isMod = Server.Mods.Contains(name.ToLower());
  922. isGCMod = Server.GCmods.Contains(name.ToLower());
  923. isStaff = isDev || isMod || isGCMod;
  924. isProtected = Server.forgeProtection == ForgeProtection.Mod && (isMod || isDev) ? true : Server.forgeProtection == ForgeProtection.Dev && isDev ? true : false;
  925. }
  926. try
  927. {
  928. Server.TempBan tBan = Server.tempBans.Find(tB => tB.name.ToLower() == name.ToLower());
  929. if (tBan.allowedJoin < DateTime.Now)
  930. {
  931. Server.tempBans.Remove(tBan);
  932. }
  933. else if (!isDev && !isMod)
  934. {
  935. Kick("You're still banned (temporary ban)!");
  936. }
  937. }
  938. catch { }
  939. // Whitelist check.
  940. if (Server.useWhitelist)
  941. {
  942. if (Server.verify)
  943. {
  944. if (Server.whiteList.Contains(name))
  945. {
  946. onWhitelist = true;
  947. }
  948. }
  949. else
  950. {
  951. // Verify Names is off. Gotta check the hard way.
  952. Database.AddParams("@IP", ip);
  953. DataTable ipQuery = Database.fillData("SELECT Name FROM Players WHERE IP = @IP");
  954. if (ipQuery.Rows.Count > 0)
  955. {
  956. if (ipQuery.Rows.Contains(name) && Server.whiteList.Contains(name))
  957. {
  958. onWhitelist = true;
  959. }
  960. }
  961. ipQuery.Dispose();
  962. }
  963. onWhitelist = isDev || isMod;
  964. if (!onWhitelist) { Kick("This is a private server!"); return; } //i think someone forgot this?
  965. }
  966. //premium check
  967. if (Server.PremiumPlayersOnly && !isDev && !isMod)
  968. {
  969. using (WebClient Client = new WebClient())
  970. {
  971. int tries = 0;
  972. while (tries++ < 3)
  973. {
  974. try
  975. {
  976. bool haspaid = Convert.ToBoolean(Client.DownloadString("http://www.minecraft.net/haspaid.jsp?user=" + name));
  977. if (!haspaid)
  978. Kick("Sorry, this is a premium server only!");
  979. break;
  980. }
  981. catch { }
  982. }
  983. }
  984. }
  985. if (File.Exists("ranks/ignore/" + this.name + ".txt"))
  986. {
  987. try
  988. {
  989. string[] checklines = File.ReadAllLines("ranks/ignore/" + this.name + ".txt");
  990. foreach (string checkline in checklines)
  991. {
  992. this.listignored.Add(checkline);
  993. }
  994. File.Delete("ranks/ignore/" + this.name + ".txt");
  995. }
  996. catch
  997. {
  998. Server.s.Log("Failed to load ignore list for: " + this.name);
  999. }
  1000. }
  1001. if (File.Exists("ranks/ignore/GlobalIgnore.xml"))
  1002. {
  1003. try
  1004. {
  1005. string[] searchxmls = File.ReadAllLines("ranks/ignore/GlobalIgnore.xml");
  1006. foreach (string searchxml in searchxmls)
  1007. {
  1008. globalignores.Add(searchxml);
  1009. }
  1010. foreach (string ignorer in globalignores)
  1011. {
  1012. Player foundignore = Player.Find(ignorer);
  1013. foundignore.ignoreglobal = true;
  1014. }
  1015. File.Delete("ranks/ignore/GlobalIgnore.xml");
  1016. }
  1017. catch
  1018. {
  1019. Server.s.Log("Failed to load global ignore list!");
  1020. }
  1021. }
  1022. // ban check
  1023. if (!isDev && !isMod)
  1024. {
  1025. if (Server.bannedIP.Contains(ip))
  1026. {
  1027. if (Server.useWhitelist)
  1028. {
  1029. if (!onWhitelist)
  1030. {
  1031. Kick(Server.customBanMessage);
  1032. return;
  1033. }
  1034. }
  1035. else
  1036. {
  1037. Kick(Server.customBanMessage);
  1038. return;
  1039. }
  1040. }
  1041. if (Group.findPlayerGroup(name) == Group.findPerm(LevelPermission.Banned))
  1042. {
  1043. if (Server.useWhitelist)
  1044. {
  1045. if (!onWhitelist)
  1046. {
  1047. Kick(Server.customBanMessage);
  1048. return;
  1049. }
  1050. }
  1051. else
  1052. {
  1053. if (UsingID && Ban.IsbannedID(ID.ToString()) || !UsingID && Ban.Isbanned(name))
  1054. {
  1055. string[] data = Ban.Getbandata(name);
  1056. Kick("You were banned for \"" + data[1] + "\" by " + data[0]);
  1057. }
  1058. else
  1059. Kick(Server.customBanMessage);
  1060. return;
  1061. }
  1062. }
  1063. }
  1064. //server maxplayer check
  1065. if (!isDev && !isMod && !VIP.Find(this))
  1066. {
  1067. // Check to see how many guests we have
  1068. if (Player.players.Count >= Server.players && !IPInPrivateRange(ip)) { Kick("Server full!"); return; }
  1069. // Code for limiting no. of guests
  1070. if (Group.findPlayerGroup(name) == Group.findPerm(LevelPermission.Guest))
  1071. {
  1072. // Check to see how many guests we have
  1073. int currentNumOfGuests = Player.players.Count(pl => pl.group.Permission <= LevelPermission.Guest);
  1074. if (currentNumOfGuests >= Server.maxGuests)
  1075. {
  1076. if (Server.guestLimitNotify) GlobalMessageOps("Guest " + this.name + " couldn't log in - too many guests.");
  1077. Server.s.Log("Guest " + this.name + " couldn't log in - too many guests.");
  1078. Kick("Server has reached max number of guests");
  1079. return;
  1080. }
  1081. }
  1082. }
  1083. if (version != Server.version) { Kick("Wrong version!"); return; }
  1084. foreach (Player p in players)
  1085. {
  1086. if (p.name == name)
  1087. {
  1088. if (Server.verify)
  1089. {
  1090. p.Kick("Someone logged in as you!"); break;
  1091. }
  1092. else { Kick("Already logged in!"); return; }
  1093. }
  1094. }
  1095. if (type == 0x42)
  1096. {
  1097. extension = true;
  1098. SendExtInfo(14);
  1099. SendExtEntry("ClickDistance", 1);
  1100. SendExtEntry("CustomBlocks", 1);
  1101. SendExtEntry("HeldBlock", 1);
  1102. SendExtEntry("TextHotKey", 1);
  1103. SendExtEntry("ExtPlayerList", 1);
  1104. SendExtEntry("EnvColors", 1);
  1105. SendExtEntry("SelectionCuboid", 1);
  1106. SendExtEntry("BlockPermissions", 1);
  1107. SendExtEntry("ChangeModel", 1);
  1108. SendExtEntry("EnvMapAppearance", 1);
  1109. SendExtEntry("EnvWeatherType", 1);
  1110. SendExtEntry("HackControl", 1);
  1111. SendExtEntry("EmoteFix", 1);
  1112. SendExtEntry("MessageTypes", 1);
  1113. SendCustomBlockSupportLevel(1);
  1114. }
  1115. try { left.Remove(name.ToLower()); }
  1116. catch { }
  1117. group = Group.findPlayerGroup(name);
  1118. SendMotd();
  1119. SendMap();
  1120. Loading = true;
  1121. if (disconnected) return;
  1122. loggedIn = true;
  1123. this.id = FreeId();
  1124. lock (players)
  1125. players.Add(this);
  1126. connections.Remove(this);
  1127. Server.s.PlayerListUpdate();
  1128. //Test code to show when people come back with different accounts on the same IP
  1129. string temp = name + " is lately known as:";
  1130. bool found = false;
  1131. if (!ip.StartsWith("127.0.0."))
  1132. {
  1133. foreach (KeyValuePair<string, string> prev in left)
  1134. {
  1135. if (prev.Value == ip)
  1136. {
  1137. found = true;
  1138. temp += " " + prev.Key;
  1139. }
  1140. }
  1141. if (found)
  1142. {
  1143. if (this.group.Permission < Server.adminchatperm || Server.adminsjoinsilent == false)
  1144. {
  1145. GlobalMessageOps(temp);
  1146. //IRCBot.Say(temp, true); //Tells people in op channel on IRC
  1147. }
  1148. Server.s.Log(temp);
  1149. }
  1150. }
  1151. }
  1152. catch (Exception e)
  1153. {
  1154. Server.ErrorLog(e);
  1155. Player.GlobalMessage("An error occurred: " + e.Message);
  1156. }
  1157. //OpenClassic Client Check
  1158. SendBlockchange(0, 0, 0, 0);
  1159. Database.AddParams("@Name", name);
  1160. DataTable playerDb = Database.fillData("SELECT * FROM Players WHERE Name=@Name");
  1161. if (playerDb.Rows.Count == 0)
  1162. {
  1163. this.prefix = "";
  1164. this.time = "0 0 0 1";
  1165. this.title = "";
  1166. this.titlecolor = "";
  1167. this.color = group.color;
  1168. this.money = 0;
  1169. this.firstLogin = DateTime.Now;
  1170. this.totalLogins = 1;
  1171. this.totalKicked = 0;
  1172. this.overallDeath = 0;
  1173. this.overallBlocks = 0;
  1174. this.timeLogged = DateTime.Now;
  1175. SendMessage("Welcome " + name + "! This is your first visit.");
  1176. string query = "INSERT INTO Economy (player, money, total, purchase, payment, salary, fine) VALUES ('" + name + "', " + money + ", 0, '%cNone', '%cNone', '%cNone', '%cNone')";
  1177. if (Server.useMySQL)
  1178. {
  1179. MySQL.executeQuery(String.Format("INSERT INTO Players (Name, IP, FirstLogin, LastLogin, totalLogin, Title, totalDeaths, Money, totalBlocks, totalKicked, TimeSpent) VALUES ('{0}', '{1}', '{2:yyyy-MM-dd HH:mm:ss}', '{3:yyyy-MM-dd HH:mm:ss}', {4}, '{5}', {6}, {7}, {8}, {9}, '{10}')", name, ip, firstLogin, DateTime.Now, totalLogins, prefix, overallDeath, money, loginBlocks, totalKicked, time));
  1180. MySQL.executeQuery(query);
  1181. }
  1182. else
  1183. {
  1184. SQLite.executeQuery(String.Format("INSERT INTO Players (Name, IP, FirstLogin, LastLogin, totalLogin, Title, totalDeaths, Money, totalBlocks, totalKicked, TimeSpent) VALUES ('{0}', '{1}', '{2:yyyy-MM-dd HH:mm:ss}', '{3:yyyy-MM-dd HH:mm:ss}', {4}, '{5}', {6}, {7}, {8}, {9}, '{10}')", name, ip, firstLogin, DateTime.Now, totalLogins, prefix, overallDeath, money, loginBlocks, totalKicked, time));
  1185. SQLite.executeQuery(query);
  1186. }
  1187. }
  1188. else
  1189. {
  1190. totalLogins = int.Parse(playerDb.Rows[0]["totalLogin"].ToString()) + 1;
  1191. time = playerDb.Rows[0]["TimeSpent"].ToString();
  1192. userID = int.Parse(playerDb.Rows[0]["ID"].ToString());
  1193. firstLogin = DateTime.Parse(playerDb.Rows[0]["firstLogin"].ToString());
  1194. timeLogged = DateTime.Now;
  1195. if (playerDb.Rows[0]["Title"].ToString().Trim() != "")
  1196. {
  1197. string parse = playerDb.Rows[0]["Title"].ToString().Trim().Replace("[", "");
  1198. title = parse.Replace("]", "");
  1199. }
  1200. if (playerDb.Rows[0]["title_color"].ToString().Trim() != "")
  1201. {
  1202. titlecolor = c.Parse(playerDb.Rows[0]["title_color"].ToString().Trim());
  1203. }
  1204. else
  1205. {
  1206. titlecolor = "";
  1207. }
  1208. if (playerDb.Rows[0]["color"].ToString().Trim() != "")
  1209. {
  1210. color = c.Parse(playerDb.Rows[0]["color"].ToString().Trim());
  1211. }
  1212. else
  1213. {
  1214. color = group.color;
  1215. }
  1216. overallDeath = int.Parse(playerDb.Rows[0]["TotalDeaths"].ToString());
  1217. overallBlocks = long.Parse(playerDb.Rows[0]["totalBlocks"].ToString().Trim());
  1218. //money = int.Parse(playerDb.Rows[0]["Money"].ToString());
  1219. money = Economy.RetrieveEcoStats(this.name).money;
  1220. totalKicked = int.Parse(playerDb.Rows[0]["totalKicked"].ToString());
  1221. SendMessage("Welcome back " + color + prefix + name + Server.DefaultColor + "! You've been here " + totalLogins + " times!");
  1222. if (Server.muted.Contains(name))
  1223. {
  1224. muted = true;
  1225. GlobalMessage(name + " is still muted from the last time they went offline.");
  1226. }
  1227. }
  1228. SetPrefix();
  1229. playerDb.Dispose();
  1230. if (PlayerConnect != null)
  1231. PlayerConnect(this);
  1232. OnPlayerConnectEvent.Call(this);
  1233. DonatorPlayers atribs = Donators.GetDonationAtribs(this); //well there seem to be no donators yet, so for the time being this will stay null
  1234. if (atribs != null)
  1235. {
  1236. color = "&" + atribs.Color;
  1237. title = atribs.Title;
  1238. SetPrefix();
  1239. }
  1240. if (Server.server_owner != "" && Server.server_owner.ToLower().Equals(this.name.ToLower()))
  1241. {
  1242. if (color == Group.standard.color)
  1243. {
  1244. color = "&c";
  1245. }
  1246. if (title == "")
  1247. {
  1248. title = "Owner";
  1249. }
  1250. SetPrefix();
  1251. }
  1252. playerDb.Dispose();
  1253. //Re-implenting MCLawl-Era Dev recognition. Is harmless and does little, but is still nice.
  1254. if (isDev)
  1255. {
  1256. if (color == Group.standard.color)
  1257. {
  1258. color = "&9";
  1259. }
  1260. if (prefix == "")
  1261. {
  1262. title = "Dev";
  1263. }
  1264. SetPrefix();
  1265. Readgcrules = true; //Devs should know the rules.
  1266. }
  1267. try
  1268. {
  1269. ushort x = (ushort)((0.5 + level.spawnx) * 32);
  1270. ushort y = (ushort)((1 + level.spawny) * 32);
  1271. ushort z = (ushort)((0.5 + level.spawnz) * 32);
  1272. pos = new ushort[3] { x, y, z }; rot = new byte[2] { level.rotx, level.roty };
  1273. GlobalSpawn(this, x, y, z, rot[0], rot[1], true);
  1274. foreach (Player p in players)
  1275. {
  1276. if (p.level == level && p != this && !p.hidden)
  1277. SendSpawn(p.id, p.color + p.name, p.pos[0], p.pos[1], p.pos[2], p.rot[0], p.rot[1]);
  1278. }
  1279. foreach (PlayerBot pB in PlayerBot.playerbots)
  1280. {
  1281. if (pB.level == level)
  1282. SendSpawn(pB.id, pB.color + pB.name, pB.pos[0], pB.pos[1], pB.pos[2], pB.rot[0], pB.rot[1]);
  1283. }
  1284. Player.players.ForEach(delegate(Player p)
  1285. {
  1286. if (p != this && extension)
  1287. {
  1288. p.SendExtAddPlayerName(id, name, group, color + name);
  1289. }
  1290. if (extension)
  1291. {
  1292. SendExtAddPlayerName(p.id, p.name, p.group, p.color + p.name);
  1293. }
  1294. });
  1295. }
  1296. catch (Exception e)
  1297. {
  1298. Server.ErrorLog(e);
  1299. Server.s.Log("Error spawning player \"" + name + "\"");
  1300. }
  1301. Loading = false;
  1302. if (Server.verifyadmins == true)
  1303. {
  1304. if (this.group.Permission >= Server.verifyadminsrank)
  1305. {
  1306. adminpen = true;
  1307. }
  1308. }
  1309. if (emoteList.Contains(name)) parseSmiley = false;
  1310. if (!Directory.Exists("text/login"))
  1311. {
  1312. Directory.CreateDirectory("text/login");
  1313. }
  1314. if (!File.Exists("text/login/" + this.name + ".txt"))
  1315. {
  1316. File.WriteAllText("text/login/" + this.name + ".txt", "joined the server.");
  1317. }
  1318. //very very sloppy, yes I know.. but works for the time
  1319. //^Perhaps we should update this? -EricKilla
  1320. bool gotoJail = false;
  1321. string gotoJailMap = "";
  1322. string gotoJailName = "";
  1323. try
  1324. {
  1325. if (File.Exists("ranks/jailed.txt"))
  1326. {
  1327. using (StreamReader read = new StreamReader("ranks/jailed.txt"))
  1328. {
  1329. string line;
  1330. while ((line = read.ReadLine()) != null)
  1331. {
  1332. if (line.Split()[0].ToLower() == this.name.ToLower())
  1333. {
  1334. gotoJail = true;
  1335. gotoJailMap = line.Split()[1];
  1336. gotoJailName = line.Split()[0];
  1337. break;
  1338. }
  1339. }
  1340. }
  1341. }
  1342. else { File.Create("ranks/jailed.txt").Close(); }
  1343. }
  1344. catch
  1345. {
  1346. gotoJail = false;
  1347. }
  1348. if (gotoJail)
  1349. {
  1350. try
  1351. {
  1352. Command.all.Find("goto").Use(this, gotoJailMap);
  1353. Command.all.Find("jail").Use(null, gotoJailName);
  1354. }
  1355. catch (Exception e)
  1356. {
  1357. Kick(e.ToString());
  1358. }
  1359. }
  1360. if (Server.agreetorulesonentry)
  1361. {
  1362. if (!File.Exists("ranks/agreed.txt"))
  1363. File.WriteAllText("ranks/agreed.txt", "");
  1364. var agreedFile = File.ReadAllText("ranks/agreed.txt");
  1365. if (this.group.Permission == LevelPermission.Guest)
  1366. {
  1367. if (!agreedFile.Contains(this.name.ToLower()))
  1368. SendMessage("&9You must read the &c/rules&9 and &c/agree&9 to them before you can build and use commands!");
  1369. else agreed = true;
  1370. }
  1371. else { agreed = true; }
  1372. }
  1373. else { agreed = true; }
  1374. string joinm = "&a+ " + this.color + this.prefix + this.name + Server.DefaultColor + " " + File.ReadAllText("text/login/" + this.name + ".txt");
  1375. if (this.group.Permission < Server.adminchatperm || Server.adminsjoinsilent == false)
  1376. {
  1377. if ((Server.guestJoinNotify == true && this.group.Permission <= LevelPermission.Guest) || this.group.Permission > LevelPermission.Guest)
  1378. {
  1379. Player.players.ForEach(p1 =>
  1380. {
  1381. if (p1.UsingWom)
  1382. {
  1383. byte[] buffer = new byte[65];
  1384. Player.StringFormat("^detail.user.join=" + color + name + c.white, 64).CopyTo(buffer, 1);
  1385. p1.SendRaw(13, buffer);
  1386. buffer = null;
  1387. }
  1388. else
  1389. Player.SendMessage(p1, joinm);
  1390. });
  1391. }
  1392. }
  1393. if (this.group.Permission >= Server.adminchatperm && Server.adminsjoinsilent == true)
  1394. {
  1395. this.hidden = true;
  1396. this.adminchat = true;
  1397. }
  1398. if (Server.verifyadmins)
  1399. {
  1400. if (this.group.Permission >= Server.verifyadminsrank)
  1401. {
  1402. if (!Directory.Exists("extra/passwords") || !File.Exists("extra/passwords/" + this.name + ".dat"))
  1403. {
  1404. this.SendMessage("&cPlease set your admin verification password with &a/setpass [Password]!");
  1405. }
  1406. else
  1407. {
  1408. this.SendMessage("&cPlease complete admin verification with &a/pass [Password]!");
  1409. }
  1410. }
  1411. }
  1412. try
  1413. {
  1414. Waypoint.Load(this);
  1415. //if (Waypoints.Count > 0) { this.SendMessage("Loaded " + Waypoints.Count + " waypoints!"); }
  1416. }
  1417. catch (Exception ex)
  1418. {
  1419. SendMessage("Error loading waypoints!");
  1420. Server.ErrorLog(ex);
  1421. }
  1422. try
  1423. {
  1424. if (File.Exists("ranks/muted.txt"))
  1425. {
  1426. using (StreamReader read = new StreamReader("ranks/muted.txt"))
  1427. {
  1428. string line;
  1429. while ((line = read.ReadLine()) != null)
  1430. {
  1431. if (line.ToLower() == this.name.ToLower())
  1432. {
  1433. this.muted = true;
  1434. Player.SendMessage(this, "!%cYou are still %8muted%c since your last login.");
  1435. break;
  1436. }
  1437. }
  1438. }
  1439. }
  1440. else { File.Create("ranks/muted.txt").Close(); }
  1441. }
  1442. catch { muted = false; }
  1443. if (!UsingID)
  1444. {
  1445. Server.s.Log(name + " [" + ip + "] + has joined the server.");
  1446. }
  1447. else
  1448. {
  1449. Server.s.Log(name + " [" + ip + "]" + "(" + ID + ") + has joined the server.");
  1450. }
  1451. if (Server.zombie.ZombieStatus() != 0) { Player.SendMessage(this, "There is a Zombie Survival game currently in-progress! Join it by typing /g " + Server.zombie.currentLevelName); }
  1452. }
  1453. public void SetPrefix()
  1454. { //just change the color name if someone ever decides these titles need different colors O.o I just try to match them with the ranks on mcforge.org
  1455. string viptitle = isDev ? string.Format("{1}[{0}Dev{1}] ", c.Parse("blue"), color) : isMod ? string.Format("{1}[{0}Mod{1}] ", c.Parse("lime"), color) : isGCMod ? string.Format("{1}[{0}GCMod{1}] ", c.Parse("gold"), color) : "";
  1456. prefix = (title == "") ? "" : (titlecolor == "") ? color + "[" + title + "] " : color + "[" + titlecolor + title + color + "] ";
  1457. prefix = viptitle + prefix;
  1458. }
  1459. void HandleBlockchange(byte[] message)
  1460. {
  1461. int section = 0;
  1462. try
  1463. {
  1464. //byte[] message = (byte[])m;
  1465. if (!loggedIn)
  1466. return;
  1467. if (CheckBlockSpam())
  1468. return;
  1469. section++;
  1470. ushort x = NTHO(message, 0);
  1471. ushort y = NTHO(message, 2);
  1472. ushort z = NTHO(message, 4);
  1473. byte action = message[6];
  1474. ushort type = message[7];
  1475. if (action == 1 && Server.ZombieModeOn && Server.noPillaring)
  1476. {
  1477. if (!referee)
  1478. {
  1479. if (lastYblock == y - 1 && lastXblock == x && lastZblock == z)
  1480. {
  1481. blocksStacked++;
  1482. }
  1483. else
  1484. {
  1485. blocksStacked = 0;
  1486. }
  1487. if (blocksStacked == 2)
  1488. {
  1489. SendMessage("You are pillaring! Stop before you get kicked!");
  1490. }
  1491. if (blocksStacked == 4)
  1492. {
  1493. Command.all.Find("kick").Use(null, name + " No pillaring allowed!");
  1494. }
  1495. }
  1496. }
  1497. lastYblock = y;
  1498. lastXblock = x;
  1499. lastZblock = z;
  1500. manualChange(x, y, z, action, type);
  1501. }
  1502. catch (Exception e)
  1503. {
  1504. // Don't ya just love it when the server tattles?
  1505. GlobalMessageOps(name + " has triggered a block change error");
  1506. GlobalMessageOps(e.GetType().ToString() + ": " + e.Message);
  1507. Server.ErrorLog(e);
  1508. }
  1509. }
  1510. public void manualChange(ushort x, ushort y, ushort z, byte action, ushort type)
  1511. {
  1512. if (type > 65)
  1513. {
  1514. Kick("Unknown block type!");
  1515. return;
  1516. }
  1517. ushort b = level.GetTile(x, y, z);
  1518. if (b == Block.Zero) { return; }
  1519. if (jailed || !agreed) { SendBlockchange(x, y, z, b); return; }
  1520. if (level.name.Contains("Museum " + Server.DefaultColor) && Blockchange == null)
  1521. {
  1522. return;
  1523. }
  1524. if (!deleteMode)
  1525. {
  1526. string info = level.foundInfo(x, y, z);
  1527. if (info.Contains("wait")) { return; }
  1528. }
  1529. if (!canBuild)
  1530. {
  1531. SendBlockchange(x, y, z, b);
  1532. return;
  1533. }
  1534. if (Server.verifyadmins == true)
  1535. {
  1536. if (this.adminpen == true)
  1537. {
  1538. SendBlockchange(x, y, z, b);
  1539. this.SendMessage("&cYou must use &a/pass [Password]&c to verify!");
  1540. return;
  1541. }
  1542. }
  1543. if (Server.ZombieModeOn && (action == 1 || (action == 0 && this.painting)))
  1544. {
  1545. if (Server.zombie != null && this.level.name == Server.zombie.currentLevelName && Server.limitedblocks)
  1546. {
  1547. if (blockCount == 0)
  1548. {
  1549. if (!referee)
  1550. {
  1551. SendMessage("You have no blocks left.");
  1552. SendBlockchange(x, y, z, b); return;
  1553. }
  1554. }
  1555. if (!referee)
  1556. {
  1557. blockCount--;
  1558. if (blockCount == 40 || blockCount == 30 || blockCount == 20 || blockCount <= 10 && blockCount >= 0)
  1559. {
  1560. SendMessage("Blocks Left: " + c.maroon + blockCount + Server.DefaultColor);
  1561. }
  1562. }
  1563. }
  1564. }
  1565. if (Server.lava.active && Server.lava.HasPlayer(this) && Server.lava.IsPlayerDead(this))
  1566. {
  1567. SendMessage("You are out of the round, and cannot build.");
  1568. SendBlockchange(x, y, z, b);
  1569. return;
  1570. }
  1571. Level.BlockPos bP;
  1572. bP.name = name;
  1573. bP.TimePerformed = DateTime.Now;
  1574. bP.x = x; bP.y = y; bP.z = z;
  1575. bP.type = type;
  1576. lastClick[0] = x;
  1577. lastClick[1] = y;
  1578. lastClick[2] = z;
  1579. //bool test2 = false;
  1580. if (Blockchange != null)
  1581. {
  1582. if (Blockchange.Method.ToString().IndexOf("AboutBlockchange") == -1 && !level.name.Contains("Museum " + Server.DefaultColor))
  1583. {
  1584. bP.deleted = true;
  1585. level.blockCache.Add(bP);
  1586. }
  1587. Blockchange(this, x, y, z, type);
  1588. return;
  1589. }
  1590. if (PlayerBlockChange != null)
  1591. PlayerBlockChange(this, x, y, z, type);
  1592. OnBlockChangeEvent.Call(this, x, y, z, type);
  1593. if (cancelBlock)
  1594. {
  1595. cancelBlock = false;
  1596. return;
  1597. }
  1598. if (group.Permission == LevelPermission.Banned) return;
  1599. if (group.Permission == LevelPermission.Guest)
  1600. {
  1601. int Diff = 0;
  1602. Diff = Math.Abs((int)(pos[0] / 32) - x);
  1603. Diff += Math.Abs((int)(pos[1] / 32) - y);
  1604. Diff += Math.Abs((int)(pos[2] / 32) - z);
  1605. if (Diff > 12)
  1606. {
  1607. if (lastCMD != "click")
  1608. {
  1609. Server.s.Log(name + " attempted to build with a " + Diff.ToString() + " distance offset");
  1610. GlobalMessageOps("To Ops &f-" + color + name + "&f- attempted to build with a " + Diff.ToString() + " distance offset");
  1611. SendMessage("You can't build that far away.");
  1612. SendBlockchange(x, y, z, b); return;
  1613. }
  1614. }
  1615. if (Server.antiTunnel)
  1616. {
  1617. if (!ignoreGrief && !PlayingTntWars)
  1618. {
  1619. if (y < level.depth / 2 - Server.maxDepth)
  1620. {
  1621. SendMessage("You're not allowed to build this far down!");
  1622. SendBlockchange(x, y, z, b); return;
  1623. }
  1624. }
  1625. }
  1626. }
  1627. if (b == Block.griefer_stone && group.Permission <= Server.grieferStoneRank && !isDev && !isMod)
  1628. {
  1629. if (grieferStoneWarn < 1)
  1630. SendMessage("Do not grief! This is your first warning!");
  1631. else if (grieferStoneWarn < 2)
  1632. SendMessage("Do NOT grief! Next time you will be " + (Server.grieferStoneBan ? "banned for 30 minutes" : "kicked") + "!");
  1633. else
  1634. {
  1635. if (Server.grieferStoneBan)
  1636. try { Command.all.Find("tempban").Use(null, name + " 30"); }
  1637. catch (Exception ex) { Server.ErrorLog(ex); }
  1638. else
  1639. Kick(Server.customGrieferStone ? Server.customGrieferStoneMessage : "Oh noes! You were caught griefing!");
  1640. return;
  1641. }
  1642. grieferStoneWarn++;
  1643. SendBlockchange(x, y, z, b);
  1644. return;
  1645. }
  1646. if (!Block.canPlace(this, b) && !Block.BuildIn(b) && !Block.AllowBreak(b))
  1647. {
  1648. SendMessage("Cannot build here!");
  1649. SendBlockchange(x, y, z, b);
  1650. return;
  1651. }
  1652. if (!Block.canPlace(this, type))
  1653. {
  1654. SendMessage("You can't place this block type!");
  1655. SendBlockchange(x, y, z, b);
  1656. return;
  1657. }
  1658. if (b >= 200 && b < 220)
  1659. {
  1660. SendMessage("Block is active, you cant disturb it!");
  1661. SendBlockchange(x, y, z, b);
  1662. return;
  1663. }
  1664. if (action > 1) { Kick("Unknown block action!"); }
  1665. ushort oldType = type;
  1666. type = bindings[(int)type];
  1667. //Ignores updating blocks that are the same and send block only to the player
  1668. if (b == (byte)((painting || action == 1) ? type : (byte)0))
  1669. {
  1670. if (painting || oldType != type) { SendBlockchange(x, y, z, b); } return;
  1671. }
  1672. //else
  1673. if (!painting && action == 0)
  1674. {
  1675. if (!deleteMode)
  1676. {
  1677. if (Block.portal(b)) { HandlePortal(this, x, y, z, b); return; }
  1678. if (Block.mb(b)) { HandleMsgBlock(this, x, y, z, b); return; }
  1679. }
  1680. bP.deleted = true;
  1681. level.blockCache.Add(bP);
  1682. deleteBlock(b, type, x, y, z);
  1683. }
  1684. else
  1685. {
  1686. bP.deleted = false;
  1687. level.blockCache.Add(bP);
  1688. placeBlock(b, type, x, y, z);
  1689. }
  1690. }
  1691. public void HandlePortal(Player p, ushort x, ushort y, ushort z, ushort b)
  1692. {
  1693. try
  1694. {
  1695. //safe against SQL injections because no user input is given here
  1696. DataTable Portals = Database.fillData("SELECT * FROM `Portals" + level.name + "` WHERE EntryX=" + (int)x + " AND EntryY=" + (int)y + " AND EntryZ=" + (int)z);
  1697. int LastPortal = Portals.Rows.Count - 1;
  1698. if (LastPortal > -1)
  1699. {
  1700. if (level.name != Portals.Rows[LastPortal]["ExitMap"].ToString())
  1701. {
  1702. if (level.permissionvisit > this.group.Permission)
  1703. {
  1704. Player.SendMessage(this, "You do not have the adequate rank to visit this map!");
  1705. return;
  1706. }
  1707. ignorePermission = true;
  1708. Level thisLevel = level;
  1709. Command.all.Find("goto").Use(this, Portals.Rows[LastPortal]["ExitMap"].ToString());
  1710. if (thisLevel == level) { Player.SendMessage(p, "The map the portal goes to isn't loaded."); return; }
  1711. ignorePermission = false;
  1712. }
  1713. else SendBlockchange(x, y, z, b);
  1714. while (p.Loading) { } //Wait for player to spawn in new map
  1715. Command.all.Find("move").Use(this, this.name + " " + Portals.Rows[LastPortal]["ExitX"].ToString() + " " + Portals.Rows[LastPortal]["ExitY"].ToString() + " " + Portals.Rows[LastPortal]["ExitZ"].ToString());
  1716. }
  1717. else
  1718. {
  1719. Blockchange(this, x, y, z, (byte)0);
  1720. }
  1721. Portals.Dispose();
  1722. }
  1723. catch { Player.SendMessage(p, "Portal had no exit."); return; }
  1724. }
  1725. public void HandleMsgBlock(Player p, ushort x, ushort y, ushort z, ushort b)
  1726. {
  1727. try
  1728. {
  1729. //safe against SQL injections because no user input is given here
  1730. DataTable Messages = Database.fillData("SELECT * FROM `Messages" + level.name + "` WHERE X=" + (int)x + " AND Y=" + (int)y + " AND Z=" + (int)z);
  1731. int LastMsg = Messages.Rows.Count - 1;
  1732. if (LastMsg > -1)
  1733. {
  1734. string message = Messages.Rows[LastMsg]["Message"].ToString().Trim();
  1735. if (message != prevMsg || Server.repeatMessage)
  1736. {
  1737. if (message.StartsWith("/"))
  1738. {
  1739. List<string> Message = message.Remove(0, 1).Split(' ').ToList();
  1740. string command = Message[0];
  1741. Message.RemoveAt(0);
  1742. string args = string.Join(" ", Message.ToArray());
  1743. HandleCommand(command, args);
  1744. }
  1745. else
  1746. Player.SendMessage(p, message);
  1747. prevMsg = message;
  1748. }
  1749. SendBlockchange(x, y, z, b);
  1750. }
  1751. else
  1752. {
  1753. Blockchange(this, x, y, z, (byte)0);
  1754. }
  1755. Messages.Dispose();
  1756. }
  1757. catch { Player.SendMessage(p, "No message was stored."); return; }
  1758. }
  1759. private bool checkOp()
  1760. {
  1761. return group.Permission < LevelPermission.Operator;
  1762. }
  1763. private void deleteBlock(ushort b, ushort type, ushort x, ushort y, ushort z)
  1764. {
  1765. Random rand = new Random();
  1766. int mx, mz;
  1767. if (deleteMode && b != Block.c4det) { level.Blockchange(this, x, y, z, Block.air); return; }
  1768. if (Block.tDoor(b)) { SendBlockchange(x, y, z, b); return; }
  1769. if (Block.DoorAirs(b) != 0)
  1770. {
  1771. if (level.physics != 0) level.Blockchange(x, y, z, Block.DoorAirs(b));
  1772. else SendBlockchange(x, y, z, b);
  1773. return;
  1774. }
  1775. if (Block.odoor(b) != Block.Zero)
  1776. {
  1777. if (b == Block.odoor8 || b == Block.odoor8_air)
  1778. {
  1779. level.Blockchange(this, x, y, z, Block.odoor(b));
  1780. }
  1781. else
  1782. {
  1783. SendBlockchange(x, y, z, b);
  1784. }
  1785. return;
  1786. }
  1787. switch (b)
  1788. {
  1789. case Block.door_air: //Door_air
  1790. case Block.door2_air:
  1791. case Block.door3_air:
  1792. case Block.door4_air:
  1793. case Block.door5_air:
  1794. case Block.door6_air:
  1795. case Block.door7_air:
  1796. case Block.door8_air:
  1797. case Block.door9_air:
  1798. case Block.door10_air:
  1799. case Block.door_iron_air:
  1800. case Block.door_gold_air:
  1801. case Block.door_cobblestone_air:
  1802. case Block.door_red_air:
  1803. case Block.door_dirt_air:
  1804. case Block.door_grass_air:
  1805. case Block.door_blue_air:
  1806. case Block.door_book_air:
  1807. break;
  1808. case Block.rocketstart:
  1809. if (level.physics < 2 || level.physics == 5)
  1810. {
  1811. SendBlockchange(x, y, z, b);
  1812. }
  1813. else
  1814. {
  1815. int newZ = 0, newX = 0, newY = 0;
  1816. SendBlockchange(x, y, z, Block.rocketstart);
  1817. if (rot[0] < 48 || rot[0] > (256 - 48))
  1818. newZ = -1;
  1819. else if (rot[0] > (128 - 48) && rot[0] < (128 + 48))
  1820. newZ = 1;
  1821. if (rot[0] > (64 - 48) && rot[0] < (64 + 48))
  1822. newX = 1;
  1823. else if (rot[0] > (192 - 48) && rot[0] < (192 + 48))
  1824. newX = -1;
  1825. if (rot[1] >= 192 && rot[1] <= (192 + 32))
  1826. newY = 1;
  1827. else if (rot[1] <= 64 && rot[1] >= 32)
  1828. newY = -1;
  1829. if (192 <= rot[1] && rot[1] <= 196 || 60 <= rot[1] && rot[1] <= 64) { newX = 0; newZ = 0; }
  1830. ushort b1 = level.GetTile((ushort)(x + newX * 2), (ushort)(y + newY * 2), (ushort)(z + newZ * 2));
  1831. ushort b2 = level.GetTile((ushort)(x + newX), (ushort)(y + newY), (ushort)(z + newZ));
  1832. if (b1 == Block.air && b2 == Block.air && level.CheckClear((ushort)(x + newX * 2), (ushort)(y + newY * 2), (ushort)(z + newZ * 2)) && level.CheckClear((ushort)(x + newX), (ushort)(y + newY), (ushort)(z + newZ)))
  1833. {
  1834. level.Blockchange((ushort)(x + newX * 2), (ushort)(y + newY * 2), (ushort)(z + newZ * 2), Block.rockethead);
  1835. level.Blockchange((ushort)(x + newX), (ushort)(y + newY), (ushort)(z + newZ), Block.fire);
  1836. }
  1837. }
  1838. break;
  1839. case Block.firework:
  1840. if (level.physics == 5)
  1841. {
  1842. SendBlockchange(x, y, z, b);
  1843. return;
  1844. }
  1845. if (level.physics != 0)
  1846. {
  1847. mx = rand.Next(0, 2); mz = rand.Next(0, 2);
  1848. ushort b1 = level.GetTile((ushort)(x + mx - 1), (ushort)(y + 2), (ushort)(z + mz - 1));
  1849. ushort b2 = level.GetTile((ushort)(x + mx - 1), (ushort)(y + 1), (ushort)(z + mz - 1));
  1850. if (b1 == Block.air && b2 == Block.air && level.CheckClear((ushort)(x + mx - 1), (ushort)(y + 2), (ushort)(z + mz - 1)) && level.CheckClear((ushort)(x + mx - 1), (ushort)(y + 1), (ushort)(z + mz - 1)))
  1851. {
  1852. level.Blockchange((ushort)(x + mx - 1), (ushort)(y + 2), (ushort)(z + mz - 1), Block.firework);
  1853. level.Blockchange((ushort)(x + mx - 1), (ushort)(y + 1), (ushort)(z + mz - 1), Block.lavastill, false, "wait 1 dissipate 100");
  1854. }
  1855. } SendBlockchange(x, y, z, b);
  1856. break;
  1857. case Block.c4det:
  1858. Level.C4.BlowUp(new ushort[] { x, y, z }, level);
  1859. level.Blockchange(x, y, z, Block.air);
  1860. break;
  1861. default:
  1862. level.Blockchange(this, x, y, z, (ushort)Block.air);
  1863. break;
  1864. }
  1865. if ((level.physics == 0 || level.physics == 5) && level.GetTile(x, (ushort)(y - 1), z) == 3) level.Blockchange(this, x, (ushort)(y - 1), z, 2);
  1866. }
  1867. public void placeBlock(ushort b, ushort type, ushort x, ushort y, ushort z)
  1868. {
  1869. if (Block.odoor(b) != Block.Zero) { SendMessage("oDoor here!"); return; }
  1870. switch (blockAction)
  1871. {
  1872. case 0: //normal
  1873. if (level.physics == 0 || level.physics == 5)
  1874. {
  1875. switch (type)
  1876. {
  1877. case Block.tnt:
  1878. if (!CTF.gameOn) { goto default; }
  1879. placedTNT.x = x;
  1880. placedTNT.y = y;
  1881. placedTNT.z = z;
  1882. placedTNT.isActive = true;
  1883. goto default;
  1884. case Block.darkgrey:
  1885. if (!CTF.gameOn) { goto default; }
  1886. if (isActivating) { SendMessage("&f- &cAnother mine is still activating!"); goto default; }
  1887. Thread placeMineThread = new Thread(new ThreadStart(delegate
  1888. {
  1889. placedMine.x = x;
  1890. placedMine.y = y;
  1891. placedMine.z = z;
  1892. SendMessage("&f- &SMine placed, activating...");
  1893. isActivating = true;
  1894. Thread.Sleep(CTF.mineActivationTime * 1000);
  1895. placedMine.isActive = true;
  1896. SendMessage("&f- &SMine is now active! Type /defuse to defuse...");
  1897. isActivating = false;
  1898. }));
  1899. placeMineThread.Start();
  1900. goto default;
  1901. case Block.purple:
  1902. if (placedTNT.isActive)
  1903. {
  1904. CTF.ExplodeTNT(this, placedTNT.x, placedTNT.y, placedTNT.z, CTF.tntBlastRadius);
  1905. SendBlockchange(x, y, z, Block.air);
  1906. }
  1907. else
  1908. {
  1909. goto default;
  1910. }
  1911. break;
  1912. case Block.dirt: //instant dirt to grass
  1913. if (Block.LightPass(level.GetTile(x, (ushort)(y + 1), z))) level.Blockchange(this, x, y, z, (byte)(Block.grass));
  1914. else level.Blockchange(this, x, y, z, (byte)(Block.dirt));
  1915. break;
  1916. case Block.staircasestep: //stair handler
  1917. if (level.GetTile(x, (ushort)(y - 1), z) == Block.staircasestep)
  1918. {
  1919. SendBlockchange(x, y, z, Block.air); //send the air block back only to the user.
  1920. //level.Blockchange(this, x, y, z, (byte)(null));
  1921. level.Blockchange(this, x, (ushort)(y - 1), z, (byte)(Block.staircasefull));
  1922. break;
  1923. }
  1924. //else
  1925. level.Blockchange(this, x, y, z, type);
  1926. break;
  1927. default:
  1928. level.Blockchange(this, x, y, z, type);
  1929. break;
  1930. }
  1931. }
  1932. else
  1933. {
  1934. level.Blockchange(this, x, y, z, type);
  1935. }
  1936. break;
  1937. case 6:
  1938. if (b == modeType) { SendBlockchange(x, y, z, b); return; }
  1939. level.Blockchange(this, x, y, z, modeType);
  1940. break;
  1941. case 13: //Small TNT
  1942. level.Blockchange(this, x, y, z, Block.smalltnt);
  1943. break;
  1944. case 14: //Big TNT
  1945. level.Blockchange(this, x, y, z, Block.bigtnt);
  1946. break;
  1947. case 15: //Nuke TNT
  1948. level.Blockchange(this, x, y, z, Block.nuketnt);
  1949. break;
  1950. default:
  1951. Server.s.Log(name + " is breaking something");
  1952. blockAction = 0;
  1953. break;
  1954. }
  1955. }
  1956. public void CheckPosition()
  1957. {
  1958. if (team == null)
  1959. {
  1960. return;
  1961. }
  1962. ushort x = (ushort)(pos[0] / 32);
  1963. ushort y;
  1964. ushort yh = (ushort)((pos[1] / 32)); // gets head pos
  1965. try
  1966. {
  1967. y = (ushort)((pos[1] / 32) - 1); // gets foot pos
  1968. }
  1969. catch
  1970. {
  1971. y = yh;
  1972. }
  1973. ushort z = (ushort)(pos[2] / 32);
  1974. ushort footBlock = level.GetTile(x, y, z);
  1975. ushort headBlock = level.GetTile(x, yh, z);
  1976. switch (footBlock)
  1977. {
  1978. case Block.flagbase:
  1979. CheckFlag();
  1980. break;
  1981. }
  1982. switch (headBlock)
  1983. {
  1984. case Block.air:
  1985. case Block.rope:
  1986. case Block.flagbase:
  1987. case Block.staircasestep:
  1988. case Block.cobblestoneslab:
  1989. case Block.Zero:
  1990. drownCount = 0;
  1991. break;
  1992. case Block.water:
  1993. case Block.waterstill:
  1994. case Block.water_portal:
  1995. case Block.air_portal:
  1996. if (team == null)
  1997. {
  1998. return;
  1999. }
  2000. drownCount++;
  2001. int drownPercentage = (drownCount * 100) / ((CTF.drownTime * 1000) / 250);
  2002. if (drownCount >= ((CTF.drownTime * 1000) / 250))
  2003. {
  2004. if (carryingFlag)
  2005. {
  2006. Command.all.Find("drop").Use(this, "");
  2007. }
  2008. team.SpawnPlayer(this);
  2009. }
  2010. else if (drownPercentage > 50)
  2011. {
  2012. SendMessage("You are drowning!");
  2013. }
  2014. break;
  2015. default:
  2016. if (team == null)
  2017. {
  2018. return;
  2019. }
  2020. drownCount = 0;
  2021. if (headBlock != Block.water && headBlock != Block.rope && headBlock != Block.air && headBlock != Block.flagbase)
  2022. {
  2023. deaths++;
  2024. if (carryingFlag)
  2025. {
  2026. Command.all.Find("drop").Use(this, "");
  2027. }
  2028. team.SpawnPlayer(this);
  2029. }
  2030. break;
  2031. }
  2032. players.ForEach(delegate(Player p)
  2033. {
  2034. if ((Math.Max(x, p.placedMine.x) - Math.Min(x, p.placedMine.x)) <= 3)
  2035. {
  2036. if ((Math.Max(y, p.placedMine.y) - Math.Min(y, p.placedMine.y)) <= 3)
  2037. {
  2038. if ((Math.Max(z, p.placedMine.z) - Math.Min(z, p.placedMine.z)) <= 3)
  2039. {
  2040. if (!p.placedMine.isActive || team == p.team)
  2041. {
  2042. return;
  2043. }
  2044. if (level.GetTile(p.placedMine.x, p.placedMine.y, p.placedMine.z) != Block.darkgrey)
  2045. {
  2046. p.placedMine.isActive = false;
  2047. return;
  2048. }
  2049. Player.GlobalMessage("&f- " + color + name + "&S was exploded by " + p.color + p.name + "&S's mine!");
  2050. p.killPlayer(this);
  2051. CTF.currLevel.Blockchange(p.placedMine.x, p.placedMine.y, p.placedMine.z, Block.air);
  2052. p.placedMine.isActive = false;
  2053. int radius = CTF.mineBlastRadius;
  2054. ushort minX = (ushort)(x - radius);
  2055. ushort minY = (ushort)(y - radius);
  2056. ushort minZ = (ushort)(z - radius);
  2057. ushort maxX = (ushort)(x + radius);
  2058. ushort maxY = (ushort)(y + radius);
  2059. ushort maxZ = (ushort)(z + radius);
  2060. for (ushort xx = minX; xx <= maxX; xx++)
  2061. {
  2062. for (ushort yy = minY; yy <= maxY; yy++)
  2063. {
  2064. for (ushort zz = minZ; zz <= maxZ; zz++)
  2065. {
  2066. if (level.GetTile(xx, yy, zz) != Block.blackrock && CTF.mineDestroyBlocks)
  2067. {
  2068. level.Blockchange(xx, yy, zz, Block.air);
  2069. Player.GlobalBlockchange(level, xx, yy, zz, Block.air);
  2070. }
  2071. }
  2072. }
  2073. }
  2074. }
  2075. }
  2076. }
  2077. if (((ushort)(pos[0] / 32) < level.divider && team.flagBase[0] > level.divider) || ((ushort)(pos[0] / 32) > level.divider && team.flagBase[0] < level.divider))
  2078. { // Good, he is on the opposite side, now we can check for any player contact ;);)
  2079. CTFTeam oppositeTeam = (team == CTF.redTeam) ? CTF.blueTeam : CTF.redTeam;
  2080. oppositeTeam.players.ForEach(delegate(Player pl)
  2081. {
  2082. ushort plposx = (ushort)(pl.pos[0] / 32);
  2083. ushort plposy = (ushort)(pl.pos[1] / 32);
  2084. ushort plposz = (ushort)(pl.pos[2] / 32);
  2085. if (Math.Max(x, plposx) - Math.Min(x, plposx) <= 1)
  2086. {
  2087. if (Math.Max(yh, plposy) - Math.Min(yh, plposy) <= 1)
  2088. {
  2089. if (Math.Max(z, plposz) - Math.Min(z, plposz) <= 1)
  2090. {
  2091. Player.GlobalMessage("&f- " + color + name + "&S was tagged by " + pl.color + pl.name + "&S!");
  2092. pl.killPlayer(this);
  2093. Thread.Sleep(500);
  2094. }
  2095. }
  2096. }
  2097. });
  2098. }
  2099. });
  2100. }
  2101. void CheckFlag()
  2102. {
  2103. if (!CTF.gameOn || team == null)
  2104. {
  2105. return;
  2106. }
  2107. CTFTeam oppositeTeam = (team == CTF.redTeam) ? CTF.blueTeam : CTF.redTeam;
  2108. ushort x = (ushort)(pos[0] / 32);
  2109. ushort y = (ushort)((pos[1] / 32) - 1);
  2110. ushort z = (ushort)(pos[2] / 32);
  2111. if (x == oppositeTeam.flagLocation[0])
  2112. {
  2113. if (y == oppositeTeam.flagLocation[1])
  2114. {
  2115. if (z == oppositeTeam.flagLocation[2])
  2116. {
  2117. CTF.TakeFlag(this, oppositeTeam);
  2118. }
  2119. }
  2120. }
  2121. if (x == team.flagBase[0])
  2122. {
  2123. if (z == team.flagBase[2])
  2124. {
  2125. if (team.flagIsHome && carryingFlag)
  2126. {
  2127. CTF.CaptureFlag(this, oppositeTeam);
  2128. }
  2129. }
  2130. }
  2131. if (x == team.flagLocation[0])
  2132. {
  2133. if (z == team.flagLocation[2])
  2134. {
  2135. if (!team.flagIsHome)
  2136. {
  2137. CTF.ReturnFlag(team, false);
  2138. Player.GlobalMessage("&f- " + color + name + "&S returned the " + team.color + team.name + "&S flag!");
  2139. Reward(CTF.returnFlagReward);
  2140. }
  2141. }
  2142. }
  2143. }
  2144. void HandleInput(object m)
  2145. {
  2146. if (!loggedIn || trainGrab || following != "" || frozen)
  2147. return;
  2148. /*if (CheckIfInsideBlock())
  2149. {
  2150. unchecked { this.SendPos((byte)-1, (ushort)(clippos[0] - 18), (ushort)(clippos[1] - 18), (ushort)(clippos[2] - 18), cliprot[0], cliprot[1]); }
  2151. return;
  2152. }*/
  2153. byte[] message = (byte[])m;
  2154. // byte thisid = message[0];
  2155. if (this.incountdown == true && CountdownGame.gamestatus == CountdownGameStatus.InProgress && CountdownGame.freezemode == true)
  2156. {
  2157. if (this.countdownsettemps == true)
  2158. {
  2159. countdowntempx = NTHO(message, 1);
  2160. Thread.Sleep(100);
  2161. countdowntempz = NTHO(message, 5);
  2162. Thread.Sleep(100);
  2163. countdownsettemps = false;
  2164. }
  2165. ushort x = countdowntempx;
  2166. ushort y = NTHO(message, 3);
  2167. ushort z = countdowntempz;
  2168. byte rotx = message[7];
  2169. byte roty = message[8];
  2170. pos = new ushort[3] { x, y, z };
  2171. rot = new byte[2] { rotx, roty };
  2172. if (countdowntempx != NTHO(message, 1) || countdowntempz != NTHO(message, 5))
  2173. {
  2174. unchecked { this.SendPos((byte)-1, pos[0], pos[1], pos[2], rot[0], rot[1]); }
  2175. }
  2176. }
  2177. else
  2178. {
  2179. ushort x = NTHO(message, 1);
  2180. ushort y = NTHO(message, 3);
  2181. ushort z = NTHO(message, 5);
  2182. if (!this.referee && Server.noRespawn && Server.ZombieModeOn)
  2183. {
  2184. if (this.pos[0] >= x + 70 || this.pos[0] <= x - 70)
  2185. {
  2186. unchecked { SendPos((byte)-1, pos[0], pos[1], pos[2], rot[0], rot[1]); }
  2187. return;
  2188. }
  2189. if (this.pos[2] >= z + 70 || this.pos[2] <= z - 70)
  2190. {
  2191. unchecked { SendPos((byte)-1, pos[0], pos[1], pos[2], rot[0], rot[1]); }
  2192. return;
  2193. }
  2194. }
  2195. if (OnMove != null)
  2196. OnMove(this, x, y, z);
  2197. if (PlayerMove != null)
  2198. PlayerMove(this, x, y, z);
  2199. PlayerMoveEvent.Call(this, x, y, z);
  2200. if (OnRotate != null)
  2201. OnRotate(this, rot);
  2202. if (PlayerRotate != null)
  2203. PlayerRotate(this, rot);
  2204. PlayerRotateEvent.Call(this, rot);
  2205. if (cancelmove)
  2206. {
  2207. unchecked { SendPos((byte)-1, pos[0], pos[1], pos[2], rot[0], rot[1]); }
  2208. return;
  2209. }
  2210. byte rotx = message[7];
  2211. byte roty = message[8];
  2212. pos = new ushort[3] { x, y, z };
  2213. rot = new byte[2] { rotx, roty };
  2214. /*if (!CheckIfInsideBlock())
  2215. {
  2216. clippos = pos;
  2217. cliprot = rot;
  2218. }*/
  2219. }
  2220. }
  2221. public void RealDeath(ushort x, ushort y, ushort z)
  2222. {
  2223. ushort b = level.GetTile(x, (ushort)(y - 2), z);
  2224. ushort b1 = level.GetTile(x, y, z);
  2225. if (oldBlock != (ushort)(x + y + z))
  2226. {
  2227. if (Block.Convert(b) == Block.air)
  2228. {
  2229. deathCount++;
  2230. deathblock = Block.air;
  2231. return;
  2232. }
  2233. else
  2234. {
  2235. if (deathCount > level.fall && deathblock == Block.air)
  2236. {
  2237. HandleDeath(deathblock);
  2238. deathCount = 0;
  2239. }
  2240. else if (deathblock != Block.water)
  2241. {
  2242. deathCount = 0;
  2243. }
  2244. }
  2245. }
  2246. switch (Block.Convert(b1))
  2247. {
  2248. case Block.water:
  2249. case Block.waterstill:
  2250. case Block.lava:
  2251. case Block.lavastill:
  2252. deathCount++;
  2253. deathblock = Block.water;
  2254. if (deathCount > level.drown * 200)
  2255. {
  2256. HandleDeath(deathblock);
  2257. deathCount = 0;
  2258. }
  2259. break;
  2260. default:
  2261. deathCount = 0;
  2262. break;
  2263. }
  2264. }
  2265. public void CheckBlock(ushort x, ushort y, ushort z)
  2266. {
  2267. y = (ushort)Math.Round((decimal)(((y * 32) + 4) / 32));
  2268. ushort b = this.level.GetTile(x, y, z);
  2269. ushort b1 = this.level.GetTile(x, (ushort)((int)y - 1), z);
  2270. if (Block.Mover(b) || Block.Mover(b1))
  2271. {
  2272. if (Block.DoorAirs(b) != 0)
  2273. level.Blockchange(x, y, z, Block.DoorAirs(b));
  2274. if (Block.DoorAirs(b1) != 0)
  2275. level.Blockchange(x, (ushort)(y - 1), z, Block.DoorAirs(b1));
  2276. if ((x + y + z) != oldBlock)
  2277. {
  2278. if (b == Block.air_portal || b == Block.water_portal || b == Block.lava_portal)
  2279. {
  2280. HandlePortal(this, x, y, z, b);
  2281. }
  2282. else if (b1 == Block.air_portal || b1 == Block.water_portal || b1 == Block.lava_portal)
  2283. {
  2284. HandlePortal(this, x, (ushort)((int)y - 1), z, b1);
  2285. }
  2286. if (b == Block.MsgAir || b == Block.MsgWater || b == Block.MsgLava)
  2287. {
  2288. HandleMsgBlock(this, x, y, z, b);
  2289. }
  2290. else if (b1 == Block.MsgAir || b1 == Block.MsgWater || b1 == Block.MsgLava)
  2291. {
  2292. HandleMsgBlock(this, x, (ushort)((int)y - 1), z, b1);
  2293. }
  2294. }
  2295. }
  2296. if ((b == Block.tntexplosion || b1 == Block.tntexplosion) && PlayingTntWars) { }
  2297. else if (Block.Death(b)) HandleDeath(b); else if (Block.Death(b1)) HandleDeath(b1);
  2298. }
  2299. public void HandleDeath(ushort b, string customMessage = "", bool explode = false)
  2300. {
  2301. ushort x = (ushort)(pos[0] / 32);
  2302. ushort y = (ushort)(pos[1] / 32);
  2303. ushort z = (ushort)(pos[2] / 32);
  2304. if (OnDeath != null)
  2305. OnDeath(this, b);
  2306. if (PlayerDeath != null)
  2307. PlayerDeath(this, b);
  2308. OnPlayerDeathEvent.Call(this, b);
  2309. if (Server.lava.active && Server.lava.HasPlayer(this) && Server.lava.IsPlayerDead(this))
  2310. return;
  2311. if (lastDeath.AddSeconds(2) < DateTime.Now)
  2312. {
  2313. if (level.Killer && !invincible)
  2314. {
  2315. switch (b)
  2316. {
  2317. case Block.tntexplosion: GlobalChatLevel(this, this.color + this.prefix + this.name + Server.DefaultColor + " &cblew into pieces.", false); break;
  2318. case Block.deathair: GlobalChatLevel(this, this.color + this.prefix + this.name + Server.DefaultColor + " walked into &cnerve gas and suffocated.", false); break;
  2319. case Block.deathwater:
  2320. case Block.activedeathwater: GlobalChatLevel(this, this.color + this.prefix + this.name + Server.DefaultColor + " stepped in &dcold water and froze.", false); break;
  2321. case Block.deathlava:
  2322. case Block.activedeathlava:
  2323. case Block.fastdeathlava: GlobalChatLevel(this, this.color + this.prefix + this.name + Server.DefaultColor + " stood in &cmagma and melted.", false); break;
  2324. case Block.magma: GlobalChatLevel(this, this.color + this.prefix + this.name + Server.DefaultColor + " was hit by &cflowing magma and melted.", false); break;
  2325. case Block.geyser: GlobalChatLevel(this, this.color + this.prefix + this.name + Server.DefaultColor + " was hit by &cboiling water and melted.", false); break;
  2326. case Block.birdkill: GlobalChatLevel(this, this.color + this.prefix + this.name + Server.DefaultColor + " was hit by a &cphoenix and burnt.", false); break;
  2327. case Block.train: GlobalChatLevel(this, this.color + this.prefix + this.name + Server.DefaultColor + " was hit by a &ctrain.", false); break;
  2328. case Block.fishshark: GlobalChatLevel(this, this.color + this.prefix + this.name + Server.DefaultColor + " was eaten by a &cshark.", false); break;
  2329. case Block.fire: GlobalChatLevel(this, this.color + this.prefix + this.name + Server.DefaultColor + " burnt to a &ccrisp.", false); break;
  2330. case Block.rockethead: GlobalChatLevel(this, this.color + this.prefix + this.name + Server.DefaultColor + " was &cin a fiery explosion.", false); level.MakeExplosion(x, y, z, 0); break;
  2331. case Block.zombiebody: GlobalChatLevel(this, this.color + this.prefix + this.name + Server.DefaultColor + " died due to lack of &5brain.", false); break;
  2332. case Block.creeper: GlobalChatLevel(this, this.color + this.prefix + this.name + Server.DefaultColor + " was killed &cb-SSSSSSSSSSSSSS", false); level.MakeExplosion(x, y, z, 1); break;
  2333. case Block.air: GlobalChatLevel(this, this.color + this.prefix + this.name + Server.DefaultColor + " hit the floor &chard.", false); break;
  2334. case Block.water: GlobalChatLevel(this, this.color + this.prefix + this.name + Server.DefaultColor + " &cdrowned.", false); break;
  2335. case Block.Zero: GlobalChatLevel(this, this.color + this.prefix + this.name + Server.DefaultColor + " was &cterminated", false); break;
  2336. case Block.fishlavashark: GlobalChatLevel(this, this.color + this.prefix + this.name + Server.DefaultColor + " was eaten by a ... LAVA SHARK?!", false); break;
  2337. case Block.rock:
  2338. if (explode) level.MakeExplosion(x, y, z, 1);
  2339. GlobalChat(this, this.color + this.prefix + this.name + Server.DefaultColor + customMessage, false);
  2340. break;
  2341. case Block.stone:
  2342. if (explode) level.MakeExplosion(x, y, z, 1);
  2343. GlobalChatLevel(this, this.color + this.prefix + this.name + Server.DefaultColor + customMessage, false);
  2344. break;
  2345. }
  2346. if (team != null && this.level.ctfmode)
  2347. {
  2348. //if (carryingFlag)
  2349. //{
  2350. // level.ctfgame.DropFlag(this, hasflag);
  2351. //}
  2352. team.SpawnPlayer(this);
  2353. //this.health = 100;
  2354. }
  2355. else if (CountdownGame.playersleftlist.Contains(this))
  2356. {
  2357. CountdownGame.Death(this);
  2358. Command.all.Find("spawn").Use(this, "");
  2359. }
  2360. else if (PlayingTntWars)
  2361. {
  2362. TntWarsKillStreak = 0;
  2363. TntWarsScoreMultiplier = 1f;
  2364. }
  2365. else if (Server.lava.active && Server.lava.HasPlayer(this))
  2366. {
  2367. if (!Server.lava.IsPlayerDead(this))
  2368. {
  2369. Server.lava.KillPlayer(this);
  2370. Command.all.Find("spawn").Use(this, "");
  2371. }
  2372. }
  2373. else
  2374. {
  2375. Command.all.Find("spawn").Use(this, "");
  2376. overallDeath++;
  2377. }
  2378. if (Server.deathcount)
  2379. if (overallDeath > 0 && overallDeath % 10 == 0) GlobalChat(this, this.color + this.prefix + this.name + Server.DefaultColor + " has died &3" + overallDeath + " times", false);
  2380. }
  2381. lastDeath = DateTime.Now;
  2382. }
  2383. }
  2384. /* void HandleFly(Player p, ushort x, ushort y, ushort z) {
  2385. FlyPos pos;
  2386. ushort xx; ushort yy; ushort zz;
  2387. TempFly.Clear();
  2388. if (!flyGlass) y = (ushort)(y + 1);
  2389. for (yy = y; yy >= (ushort)(y - 1); --yy)
  2390. for (xx = (ushort)(x - 2); xx <= (ushort)(x + 2); ++xx)
  2391. for (zz = (ushort)(z - 2); zz <= (ushort)(z + 2); ++zz)
  2392. if (p.level.GetTile(xx, yy, zz) == Block.air) {
  2393. pos.x = xx; pos.y = yy; pos.z = zz;
  2394. TempFly.Add(pos);
  2395. }
  2396. FlyBuffer.ForEach(delegate(FlyPos pos2) {
  2397. try { if (!TempFly.Contains(pos2)) SendBlockchange(pos2.x, pos2.y, pos2.z, Block.air); } catch { }
  2398. });
  2399. FlyBuffer.Clear();
  2400. TempFly.ForEach(delegate(FlyPos pos3){
  2401. FlyBuffer.Add(pos3);
  2402. });
  2403. if (flyGlass) {
  2404. FlyBuffer.ForEach(delegate(FlyPos pos1) {
  2405. try { SendBlockchange(pos1.x, pos1.y, pos1.z, Block.glass); } catch { }
  2406. });
  2407. } else {
  2408. FlyBuffer.ForEach(delegate(FlyPos pos1) {
  2409. try { SendBlockchange(pos1.x, pos1.y, pos1.z, Block.waterstill); } catch { }
  2410. });
  2411. }
  2412. } */
  2413. void SendWomUsers()
  2414. {
  2415. Player.players.ForEach(delegate(Player p)
  2416. {
  2417. if (p != this)
  2418. {
  2419. byte[] buffer = new byte[65];
  2420. Player.StringFormat("^detail.user.here=" + p.color + p.name, 64).CopyTo(buffer, 1);
  2421. SendRaw(13, buffer);
  2422. buffer = null;
  2423. }
  2424. });
  2425. }
  2426. void HandleChat(byte[] message)
  2427. {
  2428. try
  2429. {
  2430. if (!loggedIn) return;
  2431. //byte[] message = (byte[])m;
  2432. string text = enc.GetString(message, 1, 64).Trim();
  2433. // removing nulls (matters for the /womid messages)
  2434. text = text.Trim('\0');
  2435. // handles the /womid client message, which displays the WoM version
  2436. if (text.Truncate(6) == "/womid")
  2437. {
  2438. string version = (text.Length <= 21 ? text.Substring(text.IndexOf(' ') + 1) : text.Substring(7, 15));
  2439. Player.GlobalMessage(c.red + "[INFO] " + color + name + "%f is using wom client");
  2440. Player.GlobalMessage(c.red + "[INFO] %fVersion: " + version);
  2441. Server.s.Log(c.red + "[INFO] " + color + name + "%f is using wom client");
  2442. Server.s.Log(c.red + "[INFO] %fVersion: " + version);
  2443. UsingWom = true;
  2444. WoMVersion = version.Split('-')[1];
  2445. SendWomUsers();
  2446. return;
  2447. }
  2448. if (MessageHasBadColorCodes(this, text)) return;
  2449. if (storedMessage != "")
  2450. {
  2451. if (!text.EndsWith(">") && !text.EndsWith("<"))
  2452. {
  2453. text = storedMessage.Replace("|>|", " ").Replace("|<|", "") + text;
  2454. storedMessage = "";
  2455. }
  2456. }
  2457. if (text.StartsWith(">") || text.StartsWith("<")) return;
  2458. if (text.EndsWith(">"))
  2459. {
  2460. storedMessage += text.Replace(">", "|>|");
  2461. SendMessage(c.teal + "Partial message: " + c.white + storedMessage.Replace("|>|", " ").Replace("|<|", ""));
  2462. return;
  2463. }
  2464. if (text.EndsWith("<"))
  2465. {
  2466. storedMessage += text.Replace("<", "|<|");
  2467. SendMessage(c.teal + "Partial message: " + c.white + storedMessage.Replace("|<|", "").Replace("|>|", " "));
  2468. return;
  2469. }
  2470. if (Regex.IsMatch(text, "%[^a-fA-F0-9]"))//This causes all players to crash!
  2471. {
  2472. SendMessage(this, "You're not allowed to send that message!");
  2473. return;
  2474. }
  2475. text = Regex.Replace(text, @"\s\s+", " ");
  2476. if (text.Any(ch => ch < 32 || ch >= 127 || ch == '&'))
  2477. {
  2478. Kick("Illegal character in chat message!");
  2479. return;
  2480. }
  2481. if (text.Length == 0)
  2482. return;
  2483. afkCount = 0;
  2484. if (text != "/afk")
  2485. {
  2486. if (Server.afkset.Contains(this.name))
  2487. {
  2488. Server.afkset.Remove(this.name);
  2489. Player.GlobalMessage("-" + this.color + this.name + Server.DefaultColor + "- is no longer AFK");
  2490. //IRCBot.Say(this.name + " is no longer AFK");
  2491. }
  2492. }
  2493. // This will allow people to type
  2494. // //Command
  2495. // and in chat it will appear as
  2496. // /Command
  2497. // Suggested by McMrCat
  2498. if (text.StartsWith("//"))
  2499. {
  2500. text = text.Remove(0, 1);
  2501. goto hello;
  2502. }
  2503. //This will make / = /repeat
  2504. //For lazy people :P
  2505. if (text == "/")
  2506. {
  2507. HandleCommand("repeat", "");
  2508. return;
  2509. }
  2510. if (text[0] == '/' || text[0] == '!')
  2511. {
  2512. text = text.Remove(0, 1);
  2513. int pos = text.IndexOf(' ');
  2514. if (pos == -1)
  2515. {
  2516. HandleCommand(text.ToLower(), "");
  2517. return;
  2518. }
  2519. string cmd = text.Substring(0, pos).ToLower();
  2520. string msg = text.Substring(pos + 1);
  2521. HandleCommand(cmd, msg);
  2522. return;
  2523. }
  2524. hello:
  2525. // People who are muted can't speak or vote
  2526. if (muted) { this.SendMessage("You are muted."); return; } //Muted: Only allow commands
  2527. // Lava Survival map vote recorder
  2528. if (Server.lava.HasPlayer(this) && Server.lava.HasVote(text.ToLower()))
  2529. {
  2530. if (Server.lava.AddVote(this, text.ToLower()))
  2531. {
  2532. SendMessage("Your vote for &5" + text.ToLower().Capitalize() + Server.DefaultColor + " has been placed. Thanks!");
  2533. Server.lava.map.ChatLevelOps(name + " voted for &5" + text.ToLower().Capitalize() + Server.DefaultColor + ".");
  2534. return;
  2535. }
  2536. else
  2537. {
  2538. SendMessage("&cYou already voted!");
  2539. return;
  2540. }
  2541. }
  2542. //CmdVoteKick core vote recorder
  2543. if (Server.voteKickInProgress && text.Length == 1)
  2544. {
  2545. if (text.ToLower() == "y")
  2546. {
  2547. this.voteKickChoice = VoteKickChoice.Yes;
  2548. SendMessage("Thanks for voting!");
  2549. return;
  2550. }
  2551. if (text.ToLower() == "n")
  2552. {
  2553. this.voteKickChoice = VoteKickChoice.No;
  2554. SendMessage("Thanks for voting!");
  2555. return;
  2556. }
  2557. }
  2558. // Put this after vote collection so that people can vote even when chat is moderated
  2559. if (Server.chatmod && !this.voice) { this.SendMessage("Chat moderation is on, you cannot speak."); return; }
  2560. // Filter out bad words
  2561. if (Server.profanityFilter == true)
  2562. {
  2563. text = ProfanityFilter.Parse(text);
  2564. }
  2565. if (Server.checkspam == true)
  2566. {
  2567. //if (consecutivemessages == 0)
  2568. //{
  2569. // consecutivemessages++;
  2570. //}
  2571. if (Player.lastMSG == this.name)
  2572. {
  2573. consecutivemessages++;
  2574. }
  2575. else
  2576. {
  2577. consecutivemessages--;
  2578. }
  2579. if (this.consecutivemessages >= Server.spamcounter)
  2580. {
  2581. int total = Server.mutespamtime;
  2582. Command.all.Find("mute").Use(null, this.name);
  2583. Player.GlobalMessage(this.name + " has been &0muted &efor spamming!");
  2584. muteTimer.Elapsed += delegate
  2585. {
  2586. total--;
  2587. if (total <= 0)
  2588. {
  2589. muteTimer.Stop();
  2590. if (this.muted == true)
  2591. {
  2592. Command.all.Find("mute").Use(null, this.name);
  2593. }
  2594. this.consecutivemessages = 0;
  2595. Player.SendMessage(this, "Remember, no &cspamming &e" + "next time!");
  2596. }
  2597. };
  2598. muteTimer.Start();
  2599. return;
  2600. }
  2601. }
  2602. Player.lastMSG = this.name;
  2603. if (text.Length >= 2 && text[0] == '@' && text[1] == '@')
  2604. {
  2605. text = text.Remove(0, 2);
  2606. if (text.Length < 1) { SendMessage("No message entered"); return; }
  2607. SendChat(this, Server.DefaultColor + "[<] Console: &f" + text);
  2608. Server.s.Log("[>] " + this.name + ": " + text);
  2609. return;
  2610. }
  2611. if (text[0] == '@' || whisper)
  2612. {
  2613. string newtext = text;
  2614. if (text[0] == '@') newtext = text.Remove(0, 1).Trim();
  2615. if (whisperTo == "")
  2616. {
  2617. int pos = newtext.IndexOf(' ');
  2618. if (pos != -1)
  2619. {
  2620. string to = newtext.Substring(0, pos);
  2621. string msg = newtext.Substring(pos + 1);
  2622. HandleQuery(to, msg); return;
  2623. }
  2624. else
  2625. {
  2626. SendMessage("No message entered");
  2627. return;
  2628. }
  2629. }
  2630. else
  2631. {
  2632. HandleQuery(whisperTo, newtext);
  2633. return;
  2634. }
  2635. }
  2636. if (text[0] == '#' || opchat)
  2637. {
  2638. string newtext = text;
  2639. if (text[0] == '#') newtext = text.Remove(0, 1).Trim();
  2640. GlobalMessageOps("To Ops &f-" + color + name + "&f- " + newtext);
  2641. if (group.Permission < Server.opchatperm && !isStaff)
  2642. SendMessage("To Ops &f-" + color + name + "&f- " + newtext);
  2643. Server.s.Log("(OPs): " + name + ": " + newtext);
  2644. //Server.s.OpLog("(OPs): " + name + ": " + newtext);
  2645. //IRCBot.Say(name + ": " + newtext, true);
  2646. Server.IRC.Say(name + ": " + newtext, true);
  2647. return;
  2648. }
  2649. if (text[0] == '+' || adminchat)
  2650. {
  2651. string newtext = text;
  2652. if (text[0] == '+') newtext = text.Remove(0, 1).Trim();
  2653. GlobalMessageAdmins("To Admins &f-" + color + name + "&f- " + newtext); //to make it easy on remote
  2654. if (group.Permission < Server.adminchatperm && !isStaff)
  2655. SendMessage("To Admins &f-" + color + name + "&f- " + newtext);
  2656. Server.s.Log("(Admins): " + name + ": " + newtext);
  2657. Server.IRC.Say(name + ": " + newtext, true);
  2658. return;
  2659. }
  2660. if (InGlobalChat)
  2661. {
  2662. Command.all.Find("global").Use(this, text); //Didn't want to rewrite the whole command... you lazy bastard :3
  2663. return;
  2664. }
  2665. if (text[0] == ':')
  2666. {
  2667. if (PlayingTntWars)
  2668. {
  2669. string newtext = text;
  2670. if (text[0] == ':') newtext = text.Remove(0, 1).Trim();
  2671. TntWarsGame it = TntWarsGame.GetTntWarsGame(this);
  2672. if (it.GameMode == TntWarsGame.TntWarsGameMode.TDM)
  2673. {
  2674. TntWarsGame.player pl = it.FindPlayer(this);
  2675. foreach (TntWarsGame.player p in it.Players)
  2676. {
  2677. if (pl.Red && p.Red) SendMessage(p.p, "To Team " + c.red + "-" + color + name + c.red + "- " + Server.DefaultColor + newtext);
  2678. if (pl.Blue && p.Blue) SendMessage(p.p, "To Team " + c.blue + "-" + color + name + c.blue + "- " + Server.DefaultColor + newtext);
  2679. }
  2680. Server.s.Log("[TNT Wars] [TeamChat (" + (pl.Red ? "Red" : "Blue") + ") " + name + " " + newtext);
  2681. return;
  2682. }
  2683. }
  2684. }
  2685. /*if (this.teamchat)
  2686. {
  2687. if (team == Block.air)
  2688. {
  2689. Player.SendMessage(this, "You are not on a team.");
  2690. return;
  2691. }
  2692. foreach (Player p in team.players)
  2693. {
  2694. Player.SendMessage(p, "(" + team.teamstring + ") " + this.color + this.name + ":&f " + text);
  2695. }
  2696. return;
  2697. }*/
  2698. if (this.joker)
  2699. {
  2700. if (File.Exists("text/joker.txt"))
  2701. {
  2702. Server.s.Log("<JOKER>: " + this.name + ": " + text);
  2703. Player.GlobalMessageOps(Server.DefaultColor + "<&aJ&bO&cK&5E&9R" + Server.DefaultColor + ">: " + this.color + this.name + ":&f " + text);
  2704. FileInfo jokertxt = new FileInfo("text/joker.txt");
  2705. StreamReader stRead = jokertxt.OpenText();
  2706. List<string> lines = new List<string>();
  2707. Random rnd = new Random();
  2708. int i = 0;
  2709. while (!(stRead.Peek() == -1))
  2710. lines.Add(stRead.ReadLine());
  2711. stRead.Close();
  2712. stRead.Dispose();
  2713. if (lines.Count > 0)
  2714. {
  2715. i = rnd.Next(lines.Count);
  2716. text = lines[i];
  2717. }
  2718. }
  2719. else { File.Create("text/joker.txt").Dispose(); }
  2720. }
  2721. //chatroom stuff
  2722. if (this.Chatroom != null)
  2723. {
  2724. ChatRoom(this, text, true, this.Chatroom);
  2725. return;
  2726. }
  2727. if (!level.worldChat)
  2728. {
  2729. Server.s.Log("<" + name + ">[level] " + text);
  2730. GlobalChatLevel(this, text, true);
  2731. return;
  2732. }
  2733. if (text[0] == '%')
  2734. {
  2735. string newtext = text;
  2736. if (!Server.worldChat)
  2737. {
  2738. newtext = text.Remove(0, 1).Trim();
  2739. GlobalChatWorld(this, newtext, true);
  2740. }
  2741. else
  2742. {
  2743. GlobalChat(this, newtext);
  2744. }
  2745. Server.s.Log("<" + name + "> " + newtext);
  2746. //IRCBot.Say("<" + name + "> " + newtext);
  2747. if (OnChat != null)
  2748. OnChat(this, text);
  2749. if (PlayerChat != null)
  2750. PlayerChat(this, text);
  2751. OnPlayerChatEvent.Call(this, text);
  2752. return;
  2753. }
  2754. Server.s.Log("<" + name + "> " + text);
  2755. if (OnChat != null)
  2756. OnChat(this, text);
  2757. if (PlayerChat != null)
  2758. PlayerChat(this, text);
  2759. OnPlayerChatEvent.Call(this, text);
  2760. if (cancelchat)
  2761. {
  2762. cancelchat = false;
  2763. return;
  2764. }
  2765. if (Server.worldChat)
  2766. {
  2767. GlobalChat(this, text);
  2768. }
  2769. else
  2770. {
  2771. GlobalChatLevel(this, text, true);
  2772. }
  2773. //IRCBot.Say(name + ": " + text);
  2774. }
  2775. catch (Exception e) { Server.ErrorLog(e); Player.GlobalMessage("An error occurred: " + e.Message); }
  2776. }
  2777. public void HandleCommand(string cmd, string message)
  2778. {
  2779. try
  2780. {
  2781. if (Server.verifyadmins)
  2782. {
  2783. if (cmd.ToLower() == "setpass")
  2784. {
  2785. Command.all.Find(cmd).Use(this, message);
  2786. Server.s.CommandUsed(this.name + " used /setpass");
  2787. return;
  2788. }
  2789. if (cmd.ToLower() == "pass")
  2790. {
  2791. Command.all.Find(cmd).Use(this, message);
  2792. Server.s.CommandUsed(this.name + " used /pass");
  2793. return;
  2794. }
  2795. }
  2796. if (Server.agreetorulesonentry)
  2797. {
  2798. if (cmd.ToLower() == "agree")
  2799. {
  2800. Command.all.Find(cmd).Use(this, String.Empty);
  2801. Server.s.CommandUsed(this.name + " used /agree");
  2802. return;
  2803. }
  2804. if (cmd.ToLower() == "rules")
  2805. {
  2806. Command.all.Find(cmd).Use(this, String.Empty);
  2807. Server.s.CommandUsed(this.name + " used /rules");
  2808. return;
  2809. }
  2810. if (cmd.ToLower() == "disagree")
  2811. {
  2812. Command.all.Find(cmd).Use(this, String.Empty);
  2813. Server.s.CommandUsed(this.name + " used /disagree");
  2814. return;
  2815. }
  2816. }
  2817. if (cmd == String.Empty) { SendMessage("No command entered."); return; }
  2818. if (Server.agreetorulesonentry && !agreed)
  2819. {
  2820. SendMessage("You must read /rules then agree to them with /agree!");
  2821. return;
  2822. }
  2823. if (jailed)
  2824. {
  2825. SendMessage("You cannot use any commands while jailed.");
  2826. return;
  2827. }
  2828. if (Server.verifyadmins)
  2829. {
  2830. if (this.adminpen)
  2831. {
  2832. this.SendMessage("&cYou must use &a/pass [Password]&c to verify!");
  2833. return;
  2834. }
  2835. }
  2836. if (cmd.ToLower() == "care") { SendMessage("Dmitchell94 now loves you with all his heart."); return; }
  2837. if (cmd.ToLower() == "facepalm") { SendMessage("Fenderrock87's bot army just simultaneously facepalm'd at your use of this command."); return; }
  2838. if (cmd.ToLower() == "alpaca") { SendMessage("Leitrean's Alpaca Army just raped your woman and pillaged your villages!"); return; }
  2839. //DO NOT REMOVE THE TWO COMMANDS BELOW, /PONY AND /RAINBOWDASHLIKESCOOLTHINGS. -EricKilla
  2840. if (cmd.ToLower() == "pony")
  2841. {
  2842. if (ponycount < 2)
  2843. {
  2844. GlobalMessage(this.color + this.name + Server.DefaultColor + " just so happens to be a proud brony! Everyone give " + this.color + this.name + Server.DefaultColor + " a brohoof!");
  2845. ponycount += 1;
  2846. }
  2847. else
  2848. {
  2849. SendMessage("You have used this command 2 times. You cannot use it anymore! Sorry, Brony!");
  2850. }
  2851. if (OnBecomeBrony != null)
  2852. OnBecomeBrony(this);
  2853. return;
  2854. }
  2855. if (cmd.ToLower() == "rainbowdashlikescoolthings")
  2856. {
  2857. if (rdcount < 2)
  2858. {
  2859. GlobalMessage("&1T&2H&3I&4S &5S&6E&7R&8V&9E&aR &bJ&cU&dS&eT &fG&0O&1T &22&30 &4P&CE&7R&DC&EE&9N&1T &5C&6O&7O&8L&9E&aR&b!");
  2860. rdcount += 1;
  2861. }
  2862. else
  2863. {
  2864. SendMessage("You have used this command 2 times. You cannot use it anymore! Sorry, Brony!");
  2865. }
  2866. if (OnSonicRainboom != null)
  2867. OnSonicRainboom(this);
  2868. return;
  2869. }
  2870. if (CommandHasBadColourCodes(this, message))
  2871. return;
  2872. string foundShortcut = Command.all.FindShort(cmd);
  2873. if (foundShortcut != "") cmd = foundShortcut;
  2874. if (OnCommand != null)
  2875. OnCommand(cmd, this, message);
  2876. if (PlayerCommand != null)
  2877. PlayerCommand(cmd, this, message);
  2878. OnPlayerCommandEvent.Call(cmd, this, message);
  2879. if (cancelcommand)
  2880. {
  2881. cancelcommand = false;
  2882. return;
  2883. }
  2884. try
  2885. {
  2886. int foundCb = int.Parse(cmd);
  2887. if (messageBind[foundCb] == null) { SendMessage("No CMD is stored on /" + cmd); return; }
  2888. message = messageBind[foundCb] + " " + message;
  2889. message = message.TrimEnd(' ');
  2890. cmd = cmdBind[foundCb];
  2891. }
  2892. catch { }
  2893. Command command = Command.all.Find(cmd);
  2894. //Group old = null;
  2895. if (command != null)
  2896. {
  2897. //this part checks if MCForge staff are able to USE protection commands
  2898. /*if (isProtected && Server.ProtectOver.Contains(cmd.ToLower())) {
  2899. old = Group.findPerm(this.group.Permission);
  2900. this.group = Group.findPerm(LevelPermission.Nobody);
  2901. }*/
  2902. if (Player.CommandProtected(cmd.ToLower(), message))
  2903. {
  2904. SendMessage("Cannot use command, player has protection level: " + Server.forgeProtection);
  2905. Server.s.CommandUsed(name + " used /" + cmd + " " + message);
  2906. return;
  2907. }
  2908. if (group.CanExecute(command))
  2909. {
  2910. if (cmd != "repeat") lastCMD = cmd + " " + message;
  2911. if (level.name.Contains("Museum " + Server.DefaultColor))
  2912. {
  2913. if (!command.museumUsable)
  2914. {
  2915. SendMessage("Cannot use this command while in a museum!");
  2916. return;
  2917. }
  2918. }
  2919. if (this.joker == true || this.muted == true)
  2920. {
  2921. if (cmd.ToLower() == "me")
  2922. {
  2923. SendMessage("Cannot use /me while muted or jokered.");
  2924. return;
  2925. }
  2926. }
  2927. if (cmd.ToLower() != "setpass" || cmd.ToLower() != "pass")
  2928. {
  2929. Server.s.CommandUsed(name + " used /" + cmd + " " + message);
  2930. }
  2931. try
  2932. { //opstats patch (since 5.5.11)
  2933. if (Server.opstats.Contains(cmd.ToLower()) || (cmd.ToLower() == "review" && message.ToLower() == "next" && Server.reviewlist.Count > 0))
  2934. {
  2935. Database.AddParams("@Time", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
  2936. Database.AddParams("@Name", name);
  2937. Database.AddParams("@Cmd", cmd);
  2938. Database.AddParams("@Cmdmsg", message);
  2939. Database.executeQuery("INSERT INTO Opstats (Time, Name, Cmd, Cmdmsg) VALUES (@Time, @Name, @Cmd, @Cmdmsg)");
  2940. }
  2941. }
  2942. catch { }
  2943. this.commThread = new Thread(new ThreadStart(delegate
  2944. {
  2945. try
  2946. {
  2947. command.Use(this, message);
  2948. }
  2949. catch (Exception e)
  2950. {
  2951. Server.ErrorLog(e);
  2952. Player.SendMessage(this, "An error occured when using the command!");
  2953. Player.SendMessage(this, e.GetType().ToString() + ": " + e.Message);
  2954. }
  2955. //finally { if (old != null) this.group = old; }
  2956. }));
  2957. commThread.Start();
  2958. }
  2959. else { SendMessage("You are not allowed to use \"" + cmd + "\"!"); }
  2960. }
  2961. else if (Block.Ushort(cmd.ToLower()) != Block.Zero)
  2962. {
  2963. HandleCommand("mode", cmd.ToLower());
  2964. }
  2965. else
  2966. {
  2967. bool retry = true;
  2968. switch (cmd.ToLower())
  2969. { //Check for command switching
  2970. case "guest": message = message + " " + cmd.ToLower(); cmd = "setrank"; break;
  2971. case "builder": message = message + " " + cmd.ToLower(); cmd = "setrank"; break;
  2972. case "advbuilder":
  2973. case "adv": message = message + " " + cmd.ToLower(); cmd = "setrank"; break;
  2974. case "operator":
  2975. case "op": message = message + " " + cmd.ToLower(); cmd = "setrank"; break;
  2976. case "super":
  2977. case "superop": message = message + " " + cmd.ToLower(); cmd = "setrank"; break;
  2978. case "cut": cmd = "copy"; message = "cut"; break;
  2979. case "admins": message = "superop"; cmd = "viewranks"; break;
  2980. case "ops": message = "op"; cmd = "viewranks"; break;
  2981. case "banned": message = cmd; cmd = "viewranks"; break;
  2982. case "ps": message = "ps " + message; cmd = "map"; break;
  2983. //How about we start adding commands from other softwares
  2984. //and seamlessly switch here?
  2985. case "bhb":
  2986. case "hbox": cmd = "cuboid"; message = "hollow"; break;
  2987. case "blb":
  2988. case "box": cmd = "cuboid"; break;
  2989. case "sphere": cmd = "spheroid"; break;
  2990. case "cmdlist":
  2991. case "commands": cmd = "help"; message = "old"; break;
  2992. case "cmdhelp": cmd = "help"; break;
  2993. case "worlds":
  2994. case "mapsave": cmd = "save"; break;
  2995. case "mapload": cmd = "load"; break;
  2996. case "colour": cmd = "color"; break;
  2997. case "materials": cmd = "blocks"; break;
  2998. default: retry = false; break; //Unknown command, then
  2999. }
  3000. if (retry) HandleCommand(cmd, message);
  3001. else SendMessage("Unknown command \"" + cmd + "\"!");
  3002. }
  3003. }
  3004. catch (Exception e) { Server.ErrorLog(e); SendMessage("Command failed."); }
  3005. }
  3006. void HandleQuery(string to, string message)
  3007. {
  3008. Player p = Find(to);
  3009. if (p == this) { SendMessage("Trying to talk to yourself, huh?"); return; }
  3010. if (p == null) { SendMessage("Could not find player."); return; }
  3011. if (p.hidden) { if (this.hidden == false) { Player.SendMessage(p, "Could not find player."); } }
  3012. if (p.ignoreglobal == true)
  3013. {
  3014. if (Server.globalignoreops == false)
  3015. {
  3016. if (this.group.Permission >= Server.opchatperm)
  3017. {
  3018. if (p.group.Permission < this.group.Permission)
  3019. {
  3020. Server.s.Log(name + " @" + p.name + ": " + message);
  3021. SendChat(this, Server.DefaultColor + "[<] " + p.color + p.prefix + p.name + ": &f" + message);
  3022. SendChat(p, "&9[>] " + this.color + this.prefix + this.name + ": &f" + message);
  3023. return;
  3024. }
  3025. }
  3026. }
  3027. Server.s.Log(name + " @" + p.name + ": " + message);
  3028. SendChat(this, Server.DefaultColor + "[<] " + p.color + p.prefix + p.name + ": &f" + message);
  3029. return;
  3030. }
  3031. foreach (string ignored2 in p.listignored)
  3032. {
  3033. if (ignored2 == this.name)
  3034. {
  3035. Server.s.Log(name + " @" + p.name + ": " + message);
  3036. SendChat(this, Server.DefaultColor + "[<] " + p.color + p.prefix + p.name + ": &f" + message);
  3037. return;
  3038. }
  3039. }
  3040. if (p != null && !p.hidden || p.hidden && this.group.Permission >= p.group.Permission)
  3041. {
  3042. Server.s.Log(name + " @" + p.name + ": " + message);
  3043. SendChat(this, Server.DefaultColor + "[<] " + p.color + p.prefix + p.name + ": &f" + message);
  3044. SendChat(p, "&9[>] " + this.color + this.prefix + this.name + ": &f" + message);
  3045. }
  3046. else { SendMessage("Player \"" + to + "\" doesn't exist!"); }
  3047. }
  3048. #endregion
  3049. #region == OUTGOING ==
  3050. public void SendRaw(int id)
  3051. {
  3052. SendRaw(id, new byte[0]);
  3053. }
  3054. public void SendRaw(int id, byte send)
  3055. {
  3056. SendRaw(id, new byte[] { send });
  3057. }
  3058. public void SendRaw(int id, byte[] send)
  3059. {
  3060. // Abort if socket has been closed
  3061. if (socket == null || !socket.Connected)
  3062. return;
  3063. byte[] buffer = new byte[send.Length + 1];
  3064. buffer[0] = (byte)id;
  3065. for (int i = 0; i < send.Length; i++)
  3066. {
  3067. buffer[i + 1] = send[i];
  3068. }
  3069. try
  3070. {
  3071. socket.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, delegate(IAsyncResult result) { }, Block.air);
  3072. buffer = null;
  3073. }
  3074. catch (SocketException)
  3075. {
  3076. buffer = null;
  3077. Disconnect();
  3078. #if DEBUG
  3079. Server.ErrorLog(e);
  3080. #endif
  3081. }
  3082. }
  3083. /// <summary>
  3084. /// Send the client a sound/music
  3085. /// THIS ONLY WORKS WITH CLIENTS USING OpenClassic
  3086. /// </summary>
  3087. /// <param name="filepath">The filepath of the sound file.</param>
  3088. /// <param name="volume">The volume the client will play the sound/music at</param>
  3089. /// <param name="pitch">The pitch the client will play the sound/music at</param>
  3090. /// <param name="isMusic">Wether the sound is a soundeffect or a music</param>
  3091. /// <param name="x">The X coord to play the sound at (only for soundeffects)</param>
  3092. /// <param name="y">The Y coord to play the sound at (only for soundeffects)</param>
  3093. /// <param name="z">The Z coord to play the sound at (only for soundeffects)</param>
  3094. /// <param name="loop">Wether the music should loop (only for music)</param>
  3095. public void SendSound(string filepath, float volume, float pitch, bool isMusic, float x, float y, float z, bool loop)
  3096. {
  3097. if (!isUsingOpenClassic)
  3098. return;
  3099. if (!sounds.ContainsKey(filepath))
  3100. {
  3101. string id = Path.GetRandomFileName().Replace(".", "");
  3102. string url = (IsLocalIpAddress(ip) ? ip : Server.IP) + ":" + Server.port + "/" + filepath;
  3103. sounds.Add(filepath, id + "~" + url);
  3104. byte[] tosend = new byte[130];
  3105. StringFormat(id, 64).CopyTo(tosend, 0);
  3106. StringFormat(url, 64).CopyTo(tosend, 64);
  3107. tosend[128] = (byte)0;
  3108. tosend[129] = ((isMusic) ? (byte)1 : (byte)0);
  3109. SendRaw(22, tosend);
  3110. }
  3111. string id1 = sounds[filepath].Split('~')[0];
  3112. byte[] tosend1 = new byte[86];
  3113. StringFormat(id1, 64).CopyTo(tosend1, 0);
  3114. BitConverter.GetBytes(x).CopyTo(tosend1, 64);
  3115. BitConverter.GetBytes(y).CopyTo(tosend1, 68);
  3116. BitConverter.GetBytes(z).CopyTo(tosend1, 71);
  3117. BitConverter.GetBytes(volume).CopyTo(tosend1, 75);
  3118. BitConverter.GetBytes(pitch).CopyTo(tosend1, 78);
  3119. tosend1[84] = ((isMusic) ? (byte)1 : (byte)0);
  3120. tosend1[85] = ((loop && isMusic) ? (byte)1 : (byte)0);
  3121. SendRaw(23, tosend1);
  3122. }
  3123. /// <summary>
  3124. /// Tell the client to stop playing the sound
  3125. /// </summary>
  3126. /// <param name="filepath">The filepath of the sound</param>
  3127. public void StopSound(string filepath)
  3128. {
  3129. if (!sounds.ContainsKey(filepath))
  3130. return;
  3131. byte[] idb = new byte[64];
  3132. string id = sounds[filepath].Split('~')[0];
  3133. StringFormat(id, 64).CopyTo(idb, 0);
  3134. SendRaw(24, idb);
  3135. }
  3136. public static void SendMessage(Player p, string message)
  3137. {
  3138. if (p == null) { Server.s.Log(message); return; }
  3139. SendMessage(p, MessageType.Chat, message, true);
  3140. }
  3141. public static void SendMessage(Player p, MessageType type, string message, bool colorParse)
  3142. {
  3143. if (p == null)
  3144. {
  3145. if (storeHelp)
  3146. {
  3147. storedHelp += message + "\r\n";
  3148. }
  3149. else
  3150. {
  3151. if (!Server.irc || String.IsNullOrEmpty(Server.IRC.usedCmd))
  3152. Server.s.Log(message);
  3153. else
  3154. Server.IRC.Pm(Server.IRC.usedCmd, message);
  3155. //IRCBot.Say(message, true);
  3156. }
  3157. return;
  3158. }
  3159. p.SendMessage(type, Server.DefaultColor + message, colorParse);
  3160. }
  3161. public void SendMessage(string message)
  3162. {
  3163. SendMessage(message, true);
  3164. }
  3165. public void SendMessage(string message, bool colorParse)
  3166. {
  3167. if (this == null) { Server.s.Log(message); return; }
  3168. unchecked { SendMessage(MessageType.Chat, Server.DefaultColor + message, colorParse); }
  3169. }
  3170. public void SendChat(Player p, string message)
  3171. {
  3172. if (this == null) { Server.s.Log(message); return; }
  3173. Player.SendMessage(p, message);
  3174. }
  3175. public void SendMessage(byte id, string message)
  3176. {
  3177. SendMessage(MessageType.Chat, message, true);
  3178. }
  3179. public enum MessageType
  3180. {
  3181. Chat = (byte)0,
  3182. Status1 = (byte)1,
  3183. Status2 = (byte)2,
  3184. Status3 = (byte)3,
  3185. BottomRight1 = (byte)11,
  3186. BottomRight2 = (byte)12,
  3187. BottomRight3 = (byte)13,
  3188. Announcement = (byte)100
  3189. }
  3190. public void SendMessage (MessageType type, string message, bool colorParse)
  3191. {
  3192. if (this == null) {
  3193. Server.s.Log (message);
  3194. return;
  3195. }
  3196. if (ZoneSpam.AddSeconds (2) > DateTime.Now && message.Contains ("This zone belongs to "))
  3197. return;
  3198. byte[] buffer = new byte[65];
  3199. unchecked {
  3200. buffer [0] = (byte)type;
  3201. }
  3202. StringBuilder sb = new StringBuilder (message);
  3203. if (colorParse) {
  3204. for (int i = 0; i < 10; i++) {
  3205. sb.Replace ("%" + i, "&" + i);
  3206. sb.Replace ("&" + i + " &", " &");
  3207. }
  3208. for (char ch = 'a'; ch <= 'f'; ch++) {
  3209. sb.Replace ("%" + ch, "&" + ch);
  3210. sb.Replace ("&" + ch + " &", " &");
  3211. }
  3212. // Begin fix to replace all invalid color codes typed in console or chat with "."
  3213. for (char ch = (char)0; ch <= (char)47; ch++) // Characters that cause clients to disconnect
  3214. sb.Replace ("&" + ch, String.Empty);
  3215. for (char ch = (char)58; ch <= (char)96; ch++) // Characters that cause clients to disconnect
  3216. sb.Replace ("&" + ch, String.Empty);
  3217. for (char ch = (char)103; ch <= (char)127; ch++) // Characters that cause clients to disconnect
  3218. sb.Replace ("&" + ch, String.Empty);
  3219. // End fix
  3220. }
  3221. if (Server.dollardollardollar)
  3222. sb.Replace ("$name", "$" + name);
  3223. else
  3224. sb.Replace ("$name", name);
  3225. sb.Replace ("$date", DateTime.Now.ToString ("yyyy-MM-dd"));
  3226. sb.Replace ("$time", DateTime.Now.ToString ("HH:mm:ss"));
  3227. sb.Replace ("$ip", ip);
  3228. sb.Replace ("$serverip", IsLocalIpAddress (ip) ? ip : Server.IP);
  3229. if (colorParse)
  3230. sb.Replace ("$color", color);
  3231. sb.Replace ("$rank", group.name);
  3232. sb.Replace ("$level", level.name);
  3233. sb.Replace ("$deaths", overallDeath.ToString ());
  3234. sb.Replace ("$money", money.ToString ());
  3235. sb.Replace ("$blocks", overallBlocks.ToString ());
  3236. sb.Replace ("$first", firstLogin.ToString ());
  3237. sb.Replace ("$kicked", totalKicked.ToString ());
  3238. sb.Replace ("$server", Server.name);
  3239. sb.Replace ("$motd", Server.motd);
  3240. sb.Replace ("$banned", Player.GetBannedCount ().ToString ());
  3241. sb.Replace ("$irc", Server.ircServer + " > " + Server.ircChannel);
  3242. foreach (var customReplacement in Server.customdollars) {
  3243. if (!customReplacement.Key.StartsWith ("//")) {
  3244. try {
  3245. sb.Replace (customReplacement.Key, customReplacement.Value);
  3246. } catch {
  3247. }
  3248. }
  3249. }
  3250. if (Server.parseSmiley && parseSmiley)
  3251. {
  3252. sb.Replace(":)", "(darksmile)");
  3253. sb.Replace(":D", "(smile)");
  3254. sb.Replace("<3", "(heart)");
  3255. }
  3256. byte[] stored = new byte[1];
  3257. stored[0] = (byte)1;
  3258. sb.Replace("(darksmile)", enc.GetString(stored));
  3259. stored[0] = (byte)2;
  3260. sb.Replace("(smile)", enc.GetString(stored));
  3261. stored[0] = (byte)3;
  3262. sb.Replace("(heart)", enc.GetString(stored));
  3263. stored[0] = (byte)4;
  3264. sb.Replace("(diamond)", enc.GetString(stored));
  3265. stored[0] = (byte)7;
  3266. sb.Replace("(bullet)", enc.GetString(stored));
  3267. stored[0] = (byte)8;
  3268. sb.Replace("(hole)", enc.GetString(stored));
  3269. stored[0] = (byte)11;
  3270. sb.Replace("(male)", enc.GetString(stored));
  3271. stored[0] = (byte)12;
  3272. sb.Replace("(female)", enc.GetString(stored));
  3273. stored[0] = (byte)15;
  3274. sb.Replace("(sun)", enc.GetString(stored));
  3275. stored[0] = (byte)16;
  3276. sb.Replace("(right)", enc.GetString(stored));
  3277. stored[0] = (byte)17;
  3278. sb.Replace("(left)", enc.GetString(stored));
  3279. stored[0] = (byte)19;
  3280. sb.Replace("(double)", enc.GetString(stored));
  3281. stored[0] = (byte)22;
  3282. sb.Replace("(half)", enc.GetString(stored));
  3283. stored[0] = (byte)24;
  3284. sb.Replace("(uparrow)", enc.GetString(stored));
  3285. stored[0] = (byte)25;
  3286. sb.Replace("(downarrow)", enc.GetString(stored));
  3287. stored[0] = (byte)26;
  3288. sb.Replace("(rightarrow)", enc.GetString(stored));
  3289. stored[0] = (byte)30;
  3290. sb.Replace("(up)", enc.GetString(stored));
  3291. stored[0] = (byte)31;
  3292. sb.Replace("(down)", enc.GetString(stored));
  3293. message = sb.ToString();
  3294. if (HasBadColorCodes(message))
  3295. return;
  3296. int totalTries = 0;
  3297. if (MessageRecieve != null)
  3298. MessageRecieve(this, message);
  3299. if (OnMessageRecieve != null)
  3300. OnMessageRecieve(this, message);
  3301. OnMessageRecieveEvent.Call(this, message);
  3302. if (cancelmessage)
  3303. {
  3304. cancelmessage = false;
  3305. return;
  3306. }
  3307. retryTag: try
  3308. {
  3309. foreach (string line in Wordwrap(message))
  3310. {
  3311. string newLine = line;
  3312. if (newLine.TrimEnd(' ')[newLine.TrimEnd(' ').Length - 1] < '!')
  3313. {
  3314. newLine += '\'';
  3315. }
  3316. if (HasBadColorCodes(newLine))
  3317. continue;
  3318. StringFormat(newLine, 64).CopyTo(buffer, 1);
  3319. SendRaw(13, buffer);
  3320. }
  3321. }
  3322. catch (Exception e)
  3323. {
  3324. message = "&f" + message;
  3325. totalTries++;
  3326. if (totalTries < 10) goto retryTag;
  3327. else Server.ErrorLog(e);
  3328. }
  3329. }
  3330. public void SendMotd()
  3331. {
  3332. byte[] buffer = new byte[130];
  3333. buffer[0] = (byte)8;
  3334. StringFormat(Server.name, 64).CopyTo(buffer, 1);
  3335. if (Server.UseTextures)
  3336. StringFormat("&0cfg=" + (IsLocalIpAddress(ip) ? ip : Server.IP) + ":" + Server.port + "/" + level.name + "~motd", 64).CopyTo(buffer, 65);
  3337. else
  3338. {
  3339. if (!String.IsNullOrEmpty(group.MOTD)) StringFormat(group.MOTD, 64).CopyTo(buffer, 65);
  3340. else StringFormat(Server.motd, 64).CopyTo(buffer, 65);
  3341. }
  3342. if (Block.canPlace(this, Block.blackrock))
  3343. buffer[129] = 100;
  3344. else
  3345. buffer[129] = 0;
  3346. if (OnSendMOTD != null)
  3347. {
  3348. OnSendMOTD(this, buffer);
  3349. }
  3350. SendRaw(0, buffer);
  3351. }
  3352. public void SendUserMOTD()
  3353. {
  3354. byte[] buffer = new byte[130];
  3355. // Random rand = new Random();
  3356. buffer[0] = Server.version;
  3357. if (UsingWom && (level.textures.enabled || level.motd == "texture") && group.Permission >= level.textures.LowestRank.Permission) { StringFormat(Server.name, 64).CopyTo(buffer, 1); StringFormat("&0cfg=" + (IsLocalIpAddress(ip) ? ip : Server.IP) + ":" + Server.port + "/" + level.name, 64).CopyTo(buffer, 65); }
  3358. if (level.motd == "ignore")
  3359. {
  3360. StringFormat(Server.name, 64).CopyTo(buffer, 1);
  3361. if (!String.IsNullOrEmpty(group.MOTD)) StringFormat(group.MOTD, 64).CopyTo(buffer, 65);
  3362. else StringFormat(Server.motd, 64).CopyTo(buffer, 65);
  3363. }
  3364. else StringFormat(level.motd, 128).CopyTo(buffer, 1);
  3365. if (Block.canPlace(this.group.Permission, Block.blackrock))
  3366. buffer[129] = 100;
  3367. else
  3368. buffer[129] = 0;
  3369. SendRaw(0, buffer);
  3370. }
  3371. public void SendMap()
  3372. {
  3373. if (level.blocks == null) return;
  3374. try
  3375. {
  3376. byte[] buffer = new byte[level.blocks.Length + 4];
  3377. BitConverter.GetBytes(IPAddress.HostToNetworkOrder(level.blocks.Length)).CopyTo(buffer, 0);
  3378. //ushort xx; ushort yy; ushort zz;
  3379. for ( int i = 0; i < level.blocks.Length; ++i ) {
  3380. if ( extension ) {
  3381. buffer[4 + i] = (byte)Block.Convert( level.blocks[i] );
  3382. } else {
  3383. //Fallback
  3384. buffer[4 + i] = (byte)Block.Convert( Block.ConvertCPE( level.blocks[i] ) );
  3385. }
  3386. }
  3387. SendRaw(2);
  3388. buffer = buffer.GZip();
  3389. int number = (int)Math.Ceiling(((double)buffer.Length) / 1024);
  3390. for (int i = 1; buffer.Length > 0; ++i)
  3391. {
  3392. short length = (short)Math.Min(buffer.Length, 1024);
  3393. byte[] send = new byte[1027];
  3394. HTNO(length).CopyTo(send, 0);
  3395. Buffer.BlockCopy(buffer, 0, send, 2, length);
  3396. byte[] tempbuffer = new byte[buffer.Length - length];
  3397. Buffer.BlockCopy(buffer, length, tempbuffer, 0, buffer.Length - length);
  3398. buffer = tempbuffer;
  3399. send[1026] = (byte)(i * 100 / number);
  3400. //send[1026] = (byte)(100 - (i * 100 / number)); // Backwards progress lololol...
  3401. SendRaw(3, send);
  3402. if (ip == "127.0.0.1") { }
  3403. else if (Server.updateTimer.Interval > 1000) Thread.Sleep(100);
  3404. else Thread.Sleep(10);
  3405. } buffer = new byte[6];
  3406. HTNO((short)level.width).CopyTo(buffer, 0);
  3407. HTNO((short)level.depth).CopyTo(buffer, 2);
  3408. HTNO((short)level.height).CopyTo(buffer, 4);
  3409. SendRaw(4, buffer);
  3410. Loading = false;
  3411. if (OnSendMap != null)
  3412. OnSendMap(this, buffer);
  3413. }
  3414. catch (Exception ex)
  3415. {
  3416. Command.all.Find("goto").Use(this, Server.mainLevel.name);
  3417. SendMessage("There was an error sending the map data, you have been sent to the main level.");
  3418. Server.ErrorLog(ex);
  3419. }
  3420. finally
  3421. {
  3422. //if (derp) SendMessage("Something went derp when sending the map data, you should return to the main level.");
  3423. //DateTime start = DateTime.Now;
  3424. GC.Collect();
  3425. GC.WaitForPendingFinalizers();
  3426. //Server.s.Log((DateTime.Now - start).TotalMilliseconds.ToString()); // We dont want random numbers showing up do we?
  3427. }
  3428. }
  3429. public void SendSpawn(byte id, string name, ushort x, ushort y, ushort z, byte rotx, byte roty)
  3430. {
  3431. //pos = new ushort[3] { x, y, z }; // This could be remove and not effect the server :/
  3432. //rot = new byte[2] { rotx, roty };
  3433. name = name.TrimEnd('+');
  3434. byte[] buffer = new byte[73]; buffer[0] = id;
  3435. StringFormat(name, 64).CopyTo(buffer, 1);
  3436. HTNO(x).CopyTo(buffer, 65);
  3437. HTNO(y).CopyTo(buffer, 67);
  3438. HTNO(z).CopyTo(buffer, 69);
  3439. buffer[71] = rotx; buffer[72] = roty;
  3440. SendRaw(7, buffer);
  3441. }
  3442. public void SendPos(byte id, ushort x, ushort y, ushort z, byte rotx, byte roty)
  3443. {
  3444. if (x < 0) x = 32;
  3445. if (y < 0) y = 32;
  3446. if (z < 0) z = 32;
  3447. if (x > level.width * 32) x = (ushort)(level.width * 32 - 32);
  3448. if (z > level.height * 32) z = (ushort)(level.height * 32 - 32);
  3449. if (x > 32767) x = 32730;
  3450. if (y > 32767) y = 32730;
  3451. if (z > 32767) z = 32730;
  3452. pos[0] = x; pos[1] = y; pos[2] = z;
  3453. rot[0] = rotx; rot[1] = roty;
  3454. /*
  3455. pos = new ushort[3] { x, y, z };
  3456. rot = new byte[2] { rotx, roty };*/
  3457. byte[] buffer = new byte[9]; buffer[0] = id;
  3458. HTNO(x).CopyTo(buffer, 1);
  3459. HTNO(y).CopyTo(buffer, 3);
  3460. HTNO(z).CopyTo(buffer, 5);
  3461. buffer[7] = rotx; buffer[8] = roty;
  3462. SendRaw(8, buffer);
  3463. }
  3464. // Update user type for weather or not they are opped
  3465. public void SendUserType(bool op)
  3466. {
  3467. SendRaw(15, op ? (byte)100 : (byte)0);
  3468. }
  3469. //TODO: Figure a way to SendPos without changing rotation
  3470. public void SendDie(byte id) { SendRaw(0x0C, new byte[1] { id }); }
  3471. public void SendBlockchange(ushort x, ushort y, ushort z, ushort type)
  3472. {
  3473. if (type == Block.air) { type = 0; }
  3474. if (x < 0 || y < 0 || z < 0) return;
  3475. if (type > Block.maxblocks)
  3476. {
  3477. this.SendMessage("The server was not able to detect your held block, please try again!");
  3478. return;
  3479. }
  3480. if (x >= level.width || y >= level.depth || z >= level.height) return;
  3481. byte[] buffer = new byte[7];
  3482. HTNO(x).CopyTo(buffer, 0);
  3483. HTNO(y).CopyTo(buffer, 2);
  3484. HTNO(z).CopyTo(buffer, 4);
  3485. if (extension == true)
  3486. {
  3487. buffer[6] = (byte)Block.Convert(type);
  3488. }
  3489. else
  3490. {
  3491. buffer[6] = (byte)Block.Convert(Block.ConvertCPE(type));
  3492. }
  3493. SendRaw(6, buffer);
  3494. }
  3495. void SendKick(string message) { SendRaw(14, StringFormat(message, 64)); }
  3496. void SendPing() { /*pingDelay = 0; pingDelayTimer.Start();*/ SendRaw(1); }
  3497. public void SendExtInfo(short count)
  3498. {
  3499. byte[] buffer = new byte[66];
  3500. StringFormat("MCForge Version: " + Server.Version, 64).CopyTo(buffer, 0);
  3501. HTNO(count).CopyTo(buffer, 64);
  3502. SendRaw(16, buffer);
  3503. }
  3504. public void SendExtEntry(string name, short version)
  3505. {
  3506. byte[] buffer = new byte[68];
  3507. StringFormat(name, 64).CopyTo(buffer, 0);
  3508. HTNO(version).CopyTo(buffer, 64);
  3509. SendRaw(17, buffer);
  3510. }
  3511. public void SendClickDistance(short distance)
  3512. {
  3513. byte[] buffer = new byte[2];
  3514. HTNO(distance).CopyTo(buffer, 0);
  3515. SendRaw(18, buffer);
  3516. }
  3517. public void SendCustomBlockSupportLevel(byte level)
  3518. {
  3519. byte[] buffer = new byte[1];
  3520. buffer[0] = level;
  3521. SendRaw(19, buffer);
  3522. }
  3523. public void SendHoldThis(byte type, byte locked)
  3524. { // if locked is on 1, then the player can't change their selected block.
  3525. byte[] buffer = new byte[2];
  3526. buffer[0] = type;
  3527. buffer[1] = locked;
  3528. SendRaw(20, buffer);
  3529. }
  3530. public void SendTextHotKey(string label, string command, int keycode, byte mods)
  3531. {
  3532. byte[] buffer = new byte[133];
  3533. StringFormat(label, 64).CopyTo(buffer, 0);
  3534. StringFormat(command, 64).CopyTo(buffer, 64);
  3535. BitConverter.GetBytes(keycode).CopyTo(buffer, 128);
  3536. buffer[132] = mods;
  3537. SendRaw(21, buffer);
  3538. }
  3539. public void SendExtAddPlayerName(short id, string name, Group grp, string displayname = "")
  3540. {
  3541. byte[] buffer = new byte[195];
  3542. HTNO(id).CopyTo(buffer, 0);
  3543. StringFormat(name, 64).CopyTo(buffer, 2);
  3544. if (displayname == "") { displayname = name; }
  3545. StringFormat(displayname, 64).CopyTo(buffer, 66);
  3546. StringFormat(grp.color + grp.name.ToUpper() + "s:", 64).CopyTo(buffer, 130);
  3547. buffer[194] = (byte)grp.Permission.GetHashCode();
  3548. SendRaw(0x16, buffer);
  3549. }
  3550. public void SendExtAddEntity(byte id, string name, string displayname = "")
  3551. {
  3552. byte[] buffer = new byte[129];
  3553. buffer[0] = id;
  3554. StringFormat(name, 64).CopyTo(buffer, 1);
  3555. if (displayname == "") { displayname = name; }
  3556. StringFormat(displayname, 64).CopyTo(buffer, 65);
  3557. SendRaw(0x17, buffer);
  3558. }
  3559. public void SendExtRemovePlayerName(short id)
  3560. {
  3561. byte[] buffer = new byte[2];
  3562. HTNO(id).CopyTo(buffer, 0);
  3563. SendRaw(0x18, buffer);
  3564. }
  3565. public void SendEnvSetColor(byte type, short r, short g, short b)
  3566. {
  3567. byte[] buffer = new byte[7];
  3568. buffer[0] = type;
  3569. HTNO(r).CopyTo(buffer, 1);
  3570. HTNO(g).CopyTo(buffer, 3);
  3571. HTNO(b).CopyTo(buffer, 5);
  3572. SendRaw(25, buffer);
  3573. }
  3574. public void SendMakeSelection(byte id, string label, short smallx, short smally, short smallz, short bigx, short bigy, short bigz, short r, short g, short b, short opacity)
  3575. {
  3576. byte[] buffer = new byte[85];
  3577. buffer[0] = id;
  3578. StringFormat(label, 64).CopyTo(buffer, 1);
  3579. HTNO(smallx).CopyTo(buffer, 65);
  3580. HTNO(smally).CopyTo(buffer, 67);
  3581. HTNO(smallz).CopyTo(buffer, 69);
  3582. HTNO(bigx).CopyTo(buffer, 71);
  3583. HTNO(bigy).CopyTo(buffer, 73);
  3584. HTNO(bigz).CopyTo(buffer, 75);
  3585. HTNO(r).CopyTo(buffer, 77);
  3586. HTNO(g).CopyTo(buffer, 79);
  3587. HTNO(b).CopyTo(buffer, 81);
  3588. HTNO(opacity).CopyTo(buffer, 83);
  3589. SendRaw(26, buffer);
  3590. }
  3591. public void SendDeleteSelection(byte id)
  3592. {
  3593. byte[] buffer = new byte[1];
  3594. buffer[0] = id;
  3595. SendRaw(27, buffer);
  3596. }
  3597. public void SendSetBlockPermission(byte type, byte canplace, byte candelete)
  3598. {
  3599. byte[] buffer = new byte[3];
  3600. buffer[0] = type;
  3601. buffer[1] = canplace;
  3602. buffer[2] = candelete;
  3603. SendRaw(28, buffer);
  3604. }
  3605. public void SendChangeModel(byte id, string model)
  3606. {
  3607. byte[] buffer = new byte[65];
  3608. buffer[0] = id;
  3609. StringFormat(model, 64).CopyTo(buffer, 1);
  3610. SendRaw(29, buffer);
  3611. }
  3612. public void SendSetMapAppearance(string url, byte sideblock, byte edgeblock, short sidelevel)
  3613. {
  3614. byte[] buffer = new byte[68];
  3615. StringFormat(url, 64).CopyTo(buffer, 0);
  3616. buffer[64] = sideblock;
  3617. buffer[65] = edgeblock;
  3618. HTNO(sidelevel).CopyTo(buffer, 66);
  3619. SendRaw(30, buffer);
  3620. }
  3621. public void SendSetMapWeather(byte weather)
  3622. { // 0 - sunny; 1 - raining; 2 - snowing
  3623. byte[] buffer = new byte[1];
  3624. buffer[0] = weather;
  3625. SendRaw(31, buffer);
  3626. }
  3627. public void SendHackControl(byte allowflying, byte allownoclip, byte allowspeeding, byte allowrespawning, byte allowthirdperson, byte allowchangingweather, short maxjumpheight)
  3628. {
  3629. byte[] buffer = new byte[7];
  3630. buffer[0] = allowflying;
  3631. buffer[1] = allownoclip;
  3632. buffer[2] = allowspeeding;
  3633. buffer[3] = allowrespawning;
  3634. buffer[4] = allowthirdperson;
  3635. buffer[5] = allowchangingweather;
  3636. HTNO(maxjumpheight).CopyTo(buffer, 6);
  3637. SendRaw(32, buffer);
  3638. }
  3639. public void UpdatePosition()
  3640. {
  3641. //pingDelayTimer.Stop();
  3642. // Shameless copy from JTE's Server
  3643. byte changed = 0; //Denotes what has changed (x,y,z, rotation-x, rotation-y)
  3644. // 0 = no change - never happens with this code.
  3645. // 1 = position has changed
  3646. // 2 = rotation has changed
  3647. // 3 = position and rotation have changed
  3648. // 4 = Teleport Required (maybe something to do with spawning)
  3649. // 5 = Teleport Required + position has changed
  3650. // 6 = Teleport Required + rotation has changed
  3651. // 7 = Teleport Required + position and rotation has changed
  3652. //NOTE: Players should NOT be teleporting this often. This is probably causing some problems.
  3653. if (oldpos[0] != pos[0] || oldpos[1] != pos[1] || oldpos[2] != pos[2])
  3654. changed |= 1;
  3655. if (oldrot[0] != rot[0] || oldrot[1] != rot[1])
  3656. {
  3657. changed |= 2;
  3658. }
  3659. /*if (Math.Abs(pos[0] - basepos[0]) > 32 || Math.Abs(pos[1] - basepos[1]) > 32 || Math.Abs(pos[2] - basepos[2]) > 32)
  3660. changed |= 4;
  3661. if ((oldpos[0] == pos[0] && oldpos[1] == pos[1] && oldpos[2] == pos[2]) && (basepos[0] != pos[0] || basepos[1] != pos[1] || basepos[2] != pos[2]))
  3662. changed |= 4;*/
  3663. if (Math.Abs(pos[0] - oldpos[0]) > 32 || Math.Abs(pos[1] - oldpos[1]) > 32 || Math.Abs(pos[2] - oldpos[2]) > 32)
  3664. changed |= 4;
  3665. if (changed == 0) { if (oldpos[0] != pos[0] || oldpos[1] != pos[1] || oldpos[2] != pos[2]) changed |= 1; }
  3666. byte[] buffer = new byte[0]; byte msg = 0;
  3667. if ((changed & 4) != 0)
  3668. {
  3669. msg = 8; //Player teleport - used for spawning or moving too fast
  3670. buffer = new byte[9]; buffer[0] = id;
  3671. HTNO(pos[0]).CopyTo(buffer, 1);
  3672. HTNO(pos[1]).CopyTo(buffer, 3);
  3673. HTNO(pos[2]).CopyTo(buffer, 5);
  3674. buffer[7] = rot[0];
  3675. if (Server.flipHead || (this.flipHead && this.infected))
  3676. if (rot[1] > 64 && rot[1] < 192)
  3677. buffer[8] = rot[1];
  3678. else
  3679. buffer[8] = (byte)(rot[1] - (rot[1] - 128));
  3680. else
  3681. buffer[8] = rot[1];
  3682. //Realcode
  3683. //buffer[8] = rot[1];
  3684. }
  3685. else if (changed == 1)
  3686. {
  3687. try
  3688. {
  3689. msg = 10; //Position update
  3690. buffer = new byte[4]; buffer[0] = id;
  3691. Buffer.BlockCopy(System.BitConverter.GetBytes((sbyte)(pos[0] - oldpos[0])), 0, buffer, 1, 1);
  3692. Buffer.BlockCopy(System.BitConverter.GetBytes((sbyte)(pos[1] - oldpos[1])), 0, buffer, 2, 1);
  3693. Buffer.BlockCopy(System.BitConverter.GetBytes((sbyte)(pos[2] - oldpos[2])), 0, buffer, 3, 1);
  3694. }
  3695. catch { }
  3696. }
  3697. else if (changed == 2)
  3698. {
  3699. msg = 11; //Orientation update
  3700. buffer = new byte[3]; buffer[0] = id;
  3701. buffer[1] = rot[0];
  3702. if (Server.flipHead || (this.flipHead && this.infected))
  3703. if (rot[1] > 64 && rot[1] < 192)
  3704. buffer[2] = rot[1];
  3705. else
  3706. buffer[2] = (byte)(rot[1] - (rot[1] - 128));
  3707. else
  3708. buffer[2] = rot[1];
  3709. //Realcode
  3710. //buffer[2] = rot[1];
  3711. }
  3712. else if (changed == 3)
  3713. {
  3714. try
  3715. {
  3716. msg = 9; //Position and orientation update
  3717. buffer = new byte[6]; buffer[0] = id;
  3718. Buffer.BlockCopy(System.BitConverter.GetBytes((sbyte)(pos[0] - oldpos[0])), 0, buffer, 1, 1);
  3719. Buffer.BlockCopy(System.BitConverter.GetBytes((sbyte)(pos[1] - oldpos[1])), 0, buffer, 2, 1);
  3720. Buffer.BlockCopy(System.BitConverter.GetBytes((sbyte)(pos[2] - oldpos[2])), 0, buffer, 3, 1);
  3721. buffer[4] = rot[0];
  3722. if (Server.flipHead || (this.flipHead && this.infected))
  3723. if (rot[1] > 64 && rot[1] < 192)
  3724. buffer[5] = rot[1];
  3725. else
  3726. buffer[5] = (byte)(rot[1] - (rot[1] - 128));
  3727. else
  3728. buffer[5] = rot[1];
  3729. //Realcode
  3730. //buffer[5] = rot[1];
  3731. }
  3732. catch { }
  3733. }
  3734. oldpos = pos; oldrot = rot;
  3735. if (changed != 0)
  3736. try
  3737. {
  3738. foreach (Player p in players)
  3739. {
  3740. if (p != this && p.level == level)
  3741. {
  3742. p.SendRaw(msg, buffer);
  3743. }
  3744. }
  3745. }
  3746. catch { }
  3747. }
  3748. #endregion
  3749. #region == GLOBAL MESSAGES ==
  3750. public static void GlobalBlockchange(Level level, int b, ushort type)
  3751. {
  3752. ushort x, y, z;
  3753. level.IntToPos(b, out x, out y, out z);
  3754. GlobalBlockchange(level, x, y, z, type);
  3755. }
  3756. public static void GlobalBlockchange(Level level, ushort x, ushort y, ushort z, ushort type)
  3757. {
  3758. players.ForEach(delegate(Player p) { if (p.level == level) { p.SendBlockchange(x, y, z, type); } });
  3759. }
  3760. // THIS IS NOT FOR SENDING GLOBAL MESSAGES!!! IT IS TO SEND A MESSAGE FROM A SPECIFIED PLAYER!!!!!!!!!!!!!!
  3761. public static void GlobalChat(Player from, string message) { GlobalChat(from, message, true); }
  3762. public static void GlobalChat(Player from, string message, bool showname)
  3763. {
  3764. if (from == null) return; // So we don't fucking derp the hell out!
  3765. if (MessageHasBadColorCodes(from, message))
  3766. return;
  3767. if (Server.lava.HasPlayer(from) && Server.lava.HasVote(message.ToLower()))
  3768. {
  3769. if (Server.lava.AddVote(from, message.ToLower()))
  3770. {
  3771. SendMessage(from, "Your vote for &5" + message.ToLower().Capitalize() + Server.DefaultColor + " has been placed. Thanks!");
  3772. Server.lava.map.ChatLevelOps(from.name + " voted for &5" + message.ToLower().Capitalize() + Server.DefaultColor + ".");
  3773. return;
  3774. }
  3775. else
  3776. {
  3777. SendMessage(from, "&cYou already voted!");
  3778. return;
  3779. }
  3780. }
  3781. if (Server.voting == true)
  3782. {
  3783. if (message.ToLower() == "yes" || message.ToLower() == "ye" || message.ToLower() == "y")
  3784. {
  3785. if (!from.voted)
  3786. {
  3787. Server.YesVotes++;
  3788. SendMessage(from, c.red + "Thanks For Voting!");
  3789. from.voted = true;
  3790. return;
  3791. }
  3792. else if (!from.voice)
  3793. {
  3794. from.SendMessage("Chat moderation is on while voting is on!");
  3795. return;
  3796. }
  3797. }
  3798. else if (message.ToLower() == "no" || message.ToLower() == "n")
  3799. {
  3800. if (!from.voted)
  3801. {
  3802. Server.NoVotes++;
  3803. SendMessage(from, c.red + "Thanks For Voting!");
  3804. from.voted = true;
  3805. return;
  3806. }
  3807. else if (!from.voice)
  3808. {
  3809. from.SendMessage("Chat moderation is on while voting is on!");
  3810. return;
  3811. }
  3812. }
  3813. }
  3814. if (Server.votingforlevel == true)
  3815. {
  3816. if (message.ToLower() == "1" || message.ToLower() == "one")
  3817. {
  3818. if (!from.voted)
  3819. {
  3820. Server.Level1Vote++;
  3821. SendMessage(from, c.red + "Thanks For Voting!");
  3822. from.voted = true;
  3823. return;
  3824. }
  3825. else if (!from.voice)
  3826. {
  3827. from.SendMessage("Chat moderation is on while voting is on!");
  3828. return;
  3829. }
  3830. }
  3831. else if (message.ToLower() == "2" || message.ToLower() == "two")
  3832. {
  3833. if (!from.voted)
  3834. {
  3835. Server.Level2Vote++;
  3836. SendMessage(from, c.red + "Thanks For Voting!");
  3837. from.voted = true;
  3838. return;
  3839. }
  3840. else if (!from.voice)
  3841. {
  3842. from.SendMessage("Chat moderation is on while voting is on!");
  3843. return;
  3844. }
  3845. }
  3846. else if (message.ToLower() == "3" || message.ToLower() == "random" || message.ToLower() == "rand")
  3847. {
  3848. if (!from.voted)
  3849. {
  3850. Server.Level3Vote++;
  3851. SendMessage(from, c.red + "Thanks For Voting!");
  3852. from.voted = true;
  3853. return;
  3854. }
  3855. else if (!from.voice)
  3856. {
  3857. from.SendMessage("Chat moderation is on while voting is on!");
  3858. return;
  3859. }
  3860. }
  3861. else if (!from.voice)
  3862. {
  3863. from.SendMessage("Chat moderation is on while voting is on!");
  3864. return;
  3865. }
  3866. }
  3867. if (showname)
  3868. {
  3869. String referee = "";
  3870. if (from.referee)
  3871. {
  3872. referee = c.green + "[Referee] ";
  3873. }
  3874. message = referee + from.color + from.voicestring + from.color + from.prefix + from.name + ": &f" + message;
  3875. }
  3876. players.ForEach(delegate(Player p)
  3877. {
  3878. if (p.level.worldChat && p.Chatroom == null)
  3879. {
  3880. if (p.ignoreglobal == false)
  3881. {
  3882. if (from != null)
  3883. {
  3884. if (!p.listignored.Contains(from.name))
  3885. {
  3886. Player.SendMessage(p, message);
  3887. return;
  3888. }
  3889. return;
  3890. }
  3891. Player.SendMessage(p, message);
  3892. return;
  3893. }
  3894. if (Server.globalignoreops == false)
  3895. {
  3896. if (from.group.Permission >= Server.opchatperm)
  3897. {
  3898. if (p.group.Permission < from.group.Permission)
  3899. {
  3900. Player.SendMessage(p, message);
  3901. }
  3902. }
  3903. }
  3904. if (from != null)
  3905. {
  3906. if (from == p)
  3907. {
  3908. Player.SendMessage(from, message);
  3909. return;
  3910. }
  3911. }
  3912. }
  3913. });
  3914. }
  3915. public static void GlobalChatLevel(Player from, string message, bool showname)
  3916. {
  3917. if (MessageHasBadColorCodes(from, message))
  3918. return;
  3919. if (showname)
  3920. {
  3921. message = "<Level>" + from.color + from.voicestring + from.color + from.prefix + from.name + ": &f" + message;
  3922. }
  3923. players.ForEach(delegate(Player p)
  3924. {
  3925. if (p.level == from.level && p.Chatroom == null)
  3926. {
  3927. if (p.ignoreglobal == false)
  3928. {
  3929. if (from != null)
  3930. {
  3931. if (!p.listignored.Contains(from.name))
  3932. {
  3933. Player.SendMessage(p, Server.DefaultColor + message);
  3934. return;
  3935. }
  3936. return;
  3937. }
  3938. Player.SendMessage(p, Server.DefaultColor + message);
  3939. return;
  3940. }
  3941. if (Server.globalignoreops == false)
  3942. {
  3943. if (from.group.Permission >= Server.opchatperm)
  3944. {
  3945. if (p.group.Permission < from.group.Permission)
  3946. {
  3947. Player.SendMessage(p, Server.DefaultColor + message);
  3948. }
  3949. }
  3950. }
  3951. if (from != null)
  3952. {
  3953. if (from == p)
  3954. {
  3955. Player.SendMessage(from, Server.DefaultColor + message);
  3956. return;
  3957. }
  3958. }
  3959. }
  3960. });
  3961. }
  3962. public static void GlobalChatRoom(Player from, string message, bool showname)
  3963. {
  3964. if (MessageHasBadColorCodes(from, message))
  3965. return;
  3966. string oldmessage = message;
  3967. if (showname)
  3968. {
  3969. message = "<GlobalChatRoom> " + from.color + from.voicestring + from.color + from.prefix + from.name + ": &f" + message;
  3970. }
  3971. players.ForEach(delegate(Player p)
  3972. {
  3973. if (p.Chatroom != null)
  3974. {
  3975. if (p.ignoreglobal == false)
  3976. {
  3977. if (from != null)
  3978. {
  3979. if (!p.listignored.Contains(from.name))
  3980. {
  3981. Player.SendMessage(p, Server.DefaultColor + message);
  3982. return;
  3983. }
  3984. return;
  3985. }
  3986. Player.SendMessage(p, Server.DefaultColor + message);
  3987. return;
  3988. }
  3989. if (Server.globalignoreops == false)
  3990. {
  3991. if (from.group.Permission >= Server.opchatperm)
  3992. {
  3993. if (p.group.Permission < from.group.Permission)
  3994. {
  3995. Player.SendMessage(p, Server.DefaultColor + message);
  3996. }
  3997. }
  3998. }
  3999. if (from != null)
  4000. {
  4001. if (from == p)
  4002. {
  4003. Player.SendMessage(from, Server.DefaultColor + message);
  4004. return;
  4005. }
  4006. }
  4007. }
  4008. });
  4009. Server.s.Log(oldmessage + "<GlobalChatRoom>" + from.prefix + from.name + message);
  4010. }
  4011. public static void ChatRoom(Player from, string message, bool showname, string chatroom)
  4012. {
  4013. if (MessageHasBadColorCodes(from, message))
  4014. return;
  4015. string oldmessage = message;
  4016. string messageforspy = ("<ChatRoomSPY: " + chatroom + "> " + from.color + from.voicestring + from.color + from.prefix + from.name + ": &f" + message);
  4017. if (showname)
  4018. {
  4019. message = "<ChatRoom: " + chatroom + "> " + from.color + from.voicestring + from.color + from.prefix + from.name + ": &f" + message;
  4020. }
  4021. players.ForEach(delegate(Player p)
  4022. {
  4023. if (p.Chatroom == chatroom)
  4024. {
  4025. if (p.ignoreglobal == false)
  4026. {
  4027. if (from != null)
  4028. {
  4029. if (!p.listignored.Contains(from.name))
  4030. {
  4031. Player.SendMessage(p, Server.DefaultColor + message);
  4032. return;
  4033. }
  4034. return;
  4035. }
  4036. Player.SendMessage(p, Server.DefaultColor + message);
  4037. return;
  4038. }
  4039. if (Server.globalignoreops == false)
  4040. {
  4041. if (from.group.Permission >= Server.opchatperm)
  4042. {
  4043. if (p.group.Permission < from.group.Permission)
  4044. {
  4045. Player.SendMessage(p, Server.DefaultColor + message);
  4046. }
  4047. }
  4048. }
  4049. if (from != null)
  4050. {
  4051. if (from == p)
  4052. {
  4053. Player.SendMessage(from, Server.DefaultColor + message);
  4054. return;
  4055. }
  4056. }
  4057. }
  4058. });
  4059. players.ForEach(delegate(Player p)
  4060. {
  4061. if (p.spyChatRooms.Contains(chatroom) && p.Chatroom != chatroom)
  4062. {
  4063. if (p.ignoreglobal == false)
  4064. {
  4065. if (from != null)
  4066. {
  4067. if (!p.listignored.Contains(from.name))
  4068. {
  4069. Player.SendMessage(p, Server.DefaultColor + message);
  4070. return;
  4071. }
  4072. return;
  4073. }
  4074. Player.SendMessage(p, Server.DefaultColor + message);
  4075. return;
  4076. }
  4077. if (Server.globalignoreops == false)
  4078. {
  4079. if (from.group.Permission >= Server.opchatperm)
  4080. {
  4081. if (p.group.Permission < from.group.Permission)
  4082. {
  4083. Player.SendMessage(p, Server.DefaultColor + messageforspy);
  4084. }
  4085. }
  4086. }
  4087. if (from != null)
  4088. {
  4089. if (from == p)
  4090. {
  4091. Player.SendMessage(from, Server.DefaultColor + messageforspy);
  4092. return;
  4093. }
  4094. }
  4095. }
  4096. });
  4097. Server.s.Log(oldmessage + "<ChatRoom" + chatroom + ">" + from.prefix + from.name + message);
  4098. }
  4099. public static bool MessageHasBadColorCodes(Player from, string message)
  4100. {
  4101. if (HasBadColorCodes(message))
  4102. {
  4103. SendMessage(from, "Message not sent. You have bad color codes.");
  4104. return true;
  4105. }
  4106. return false;
  4107. }
  4108. public static bool HasBadColorCodes(string message)
  4109. {
  4110. string[] sections = message.Split(new[] { '&', '%' });
  4111. for (int i = 0; i < sections.Length; i++)
  4112. {
  4113. if (String.IsNullOrEmpty(sections[i].Trim()) && i == 0)
  4114. { //If it starts with a color code
  4115. continue;
  4116. }
  4117. if (String.IsNullOrEmpty(sections[i].Trim()) && i - 1 != sections.Length)
  4118. { //If it ends with a color code
  4119. continue;
  4120. }
  4121. if (String.IsNullOrEmpty(sections[i]) && i - 1 != sections.Length)
  4122. {
  4123. return true;
  4124. }
  4125. if (!IsValidColorChar(sections[i][0]))
  4126. {
  4127. sections[i] = 'a' + sections[i].Substring(1);
  4128. }
  4129. }
  4130. return false;
  4131. }
  4132. public static bool IsValidColorChar(char color)
  4133. {
  4134. return (color >= '0' && color <= '9') || (color >= 'a' && color <= 'f') || (color >= 'A' && color <= 'F');
  4135. }
  4136. public static bool HasBadColorCodesTwo(string message)
  4137. {
  4138. string[] split = message.Split('&');
  4139. for (int i = 0; i < split.Length; i++)
  4140. {
  4141. string section = split[i];
  4142. if (String.IsNullOrEmpty(section.Trim()))
  4143. return true;
  4144. if (!IsValidColorChar(section[0]))
  4145. return true;
  4146. }
  4147. return false;
  4148. }
  4149. public static bool CommandHasBadColourCodes(Player who, string message)
  4150. {
  4151. string[] checkmessagesplit = message.Split(' ');
  4152. bool lastendwithcolour = false;
  4153. foreach (string s in checkmessagesplit)
  4154. {
  4155. s.Trim();
  4156. if (s.StartsWith("%"))
  4157. {
  4158. if (lastendwithcolour)
  4159. {
  4160. if (who != null)
  4161. {
  4162. who.SendMessage("Sorry, Your colour codes in this command were invalid (You cannot use 2 colour codes next to each other");
  4163. who.SendMessage("Command failed.");
  4164. Server.s.Log(who.name + " attempted to send a command with invalid colours codes (2 colour codes were next to each other)!");
  4165. GlobalMessageOps(who.color + who.name + " " + Server.DefaultColor + " attempted to send a command with invalid colours codes (2 colour codes were next to each other)!");
  4166. }
  4167. return true;
  4168. }
  4169. else if (s.Length == 2)
  4170. {
  4171. lastendwithcolour = true;
  4172. }
  4173. }
  4174. if (s.TrimEnd(Server.ColourCodesNoPercent).EndsWith("%"))
  4175. {
  4176. lastendwithcolour = true;
  4177. }
  4178. else
  4179. {
  4180. lastendwithcolour = false;
  4181. }
  4182. }
  4183. return false;
  4184. }
  4185. public static string EscapeColours(string message)
  4186. {
  4187. try
  4188. {
  4189. int index = 1;
  4190. StringBuilder sb = new StringBuilder();
  4191. Regex r = new Regex("^[0-9a-fA-F]$");
  4192. foreach (char c in message)
  4193. {
  4194. if (c == '%')
  4195. {
  4196. if (message.Length >= index)
  4197. sb.Append(r.IsMatch(message[index].ToString()) ? '&' : '%');
  4198. else
  4199. sb.Append('%');
  4200. }
  4201. else
  4202. sb.Append(c);
  4203. index++;
  4204. }
  4205. return sb.ToString();
  4206. }
  4207. catch
  4208. {
  4209. return message;
  4210. }
  4211. }
  4212. public static void GlobalChatWorld(Player from, string message, bool showname)
  4213. {
  4214. if (showname)
  4215. {
  4216. message = "<World>" + from.color + from.voicestring + from.color + from.prefix + from.name + ": &f" + message;
  4217. }
  4218. players.ForEach(delegate(Player p)
  4219. {
  4220. if (p.level.worldChat && p.Chatroom == null)
  4221. {
  4222. if (p.ignoreglobal == false)
  4223. {
  4224. if (from != null)
  4225. {
  4226. if (!p.listignored.Contains(from.name))
  4227. {
  4228. Player.SendMessage(p, Server.DefaultColor + message);
  4229. return;
  4230. }
  4231. return;
  4232. }
  4233. Player.SendMessage(p, Server.DefaultColor + message);
  4234. return;
  4235. }
  4236. if (Server.globalignoreops == false)
  4237. {
  4238. if (from.group.Permission >= Server.opchatperm)
  4239. {
  4240. if (p.group.Permission < from.group.Permission)
  4241. {
  4242. Player.SendMessage(p, Server.DefaultColor + message);
  4243. }
  4244. }
  4245. }
  4246. if (from != null)
  4247. {
  4248. if (from == p)
  4249. {
  4250. Player.SendMessage(from, Server.DefaultColor + message);
  4251. return;
  4252. }
  4253. }
  4254. }
  4255. });
  4256. }
  4257. public static void GlobalMessage(string message)
  4258. {
  4259. GlobalMessage(MessageType.Chat, message, false);
  4260. }
  4261. public static void GlobalMessage(MessageType type, string message, bool global)
  4262. {
  4263. if (!global)
  4264. //message = message.Replace("%", "&");
  4265. message = EscapeColours(message);
  4266. players.ForEach(delegate(Player p)
  4267. {
  4268. if (p.level.worldChat && p.Chatroom == null && (!global || !p.muteGlobal))
  4269. {
  4270. Player.SendMessage(p, type, message, !global);
  4271. }
  4272. });
  4273. }
  4274. public static void GlobalMessageLevel(Level l, string message)
  4275. {
  4276. players.ForEach(delegate(Player p) { if (p.level == l && p.Chatroom == null) Player.SendMessage(p, MessageType.Chat, message, true); });
  4277. }
  4278. public static void GlobalMessageLevel(Level l, MessageType type, string message)
  4279. {
  4280. players.ForEach(delegate(Player p) { if (p.level == l && p.Chatroom == null) Player.SendMessage(p, type, message, true); });
  4281. }
  4282. public static void GlobalMessageOps(string message)
  4283. {
  4284. try
  4285. {
  4286. players.ForEach(delegate(Player p)
  4287. {
  4288. if (p.group.Permission >= Server.opchatperm || p.isStaff)
  4289. { //START
  4290. Player.SendMessage(p, message);
  4291. }
  4292. });
  4293. }
  4294. catch { Server.s.Log("Error occured with Op Chat"); }
  4295. }
  4296. public static void GlobalMessageAdmins(string message)
  4297. {
  4298. try
  4299. {
  4300. players.ForEach(delegate(Player p)
  4301. {
  4302. if (p.group.Permission >= Server.adminchatperm || p.isStaff)
  4303. {
  4304. Player.SendMessage(p, message);
  4305. }
  4306. });
  4307. }
  4308. catch { Server.s.Log("Error occured with Admin Chat"); }
  4309. }
  4310. public static void GlobalSpawn(Player from, ushort x, ushort y, ushort z, byte rotx, byte roty, bool self, string possession = "")
  4311. {
  4312. players.ForEach(delegate(Player p)
  4313. {
  4314. if (p.Loading && p != from) { return; }
  4315. if (p.level != from.level || (from.hidden && !self)) { return; }
  4316. if (p != from)
  4317. {
  4318. if (Server.ZombieModeOn && !p.aka)
  4319. {
  4320. if (from.infected)
  4321. {
  4322. if (Server.ZombieName != "")
  4323. p.SendSpawn(from.id, c.red + Server.ZombieName + possession, x, y, z, rotx, roty);
  4324. else
  4325. p.SendSpawn(from.id, c.red + from.name + possession, x, y, z, rotx, roty);
  4326. return;
  4327. }
  4328. else if (from.referee)
  4329. {
  4330. return;
  4331. }
  4332. else
  4333. {
  4334. p.SendSpawn(from.id, from.color + from.name + possession, x, y, z, rotx, roty);
  4335. return;
  4336. }
  4337. }
  4338. else
  4339. {
  4340. p.SendSpawn(from.id, from.color + from.name + possession, x, y, z, rotx, roty);
  4341. }
  4342. }
  4343. else if (self)
  4344. {
  4345. if (!p.ignorePermission)
  4346. {
  4347. p.pos = new ushort[3] { x, y, z }; p.rot = new byte[2] { rotx, roty };
  4348. p.oldpos = p.pos; p.oldrot = p.rot;
  4349. unchecked { p.SendSpawn((byte)-1, from.color + from.name + possession, x, y, z, rotx, roty); }
  4350. }
  4351. }
  4352. });
  4353. }
  4354. public static void GlobalDie(Player from, bool self)
  4355. {
  4356. players.ForEach(delegate(Player p)
  4357. {
  4358. if (p.level != from.level || (from.hidden && !self)) { return; }
  4359. if (p != from) { p.SendDie(from.id); }
  4360. else if (self) { p.SendDie(Block.maxblocks); }
  4361. });
  4362. }
  4363. public bool MarkPossessed(string marker = "")
  4364. {
  4365. if (marker != "")
  4366. {
  4367. Player controller = Player.Find(marker);
  4368. if (controller == null)
  4369. {
  4370. return false;
  4371. }
  4372. marker = " (" + controller.color + controller.name + color + ")";
  4373. }
  4374. GlobalDie(this, true);
  4375. GlobalSpawn(this, pos[0], pos[1], pos[2], rot[0], rot[1], true, marker);
  4376. return true;
  4377. }
  4378. public static void GlobalUpdate() { players.ForEach(delegate(Player p) { if (!p.hidden) { p.UpdatePosition(); } }); }
  4379. #endregion
  4380. #region == DISCONNECTING ==
  4381. public void Disconnect() { leftGame(); }
  4382. public void Kick(string kickString) { leftGame(kickString); }
  4383. internal void CloseSocket()
  4384. {
  4385. // Try to close the socket.
  4386. // Sometimes its already closed so these lines will cause an error
  4387. // We just trap them and hide them from view :P
  4388. try
  4389. {
  4390. // Close the damn socket connection!
  4391. socket.Shutdown(SocketShutdown.Both);
  4392. #if DEBUG
  4393. Server.s.Log("Socket was shutdown for " + this.name ?? this.ip);
  4394. #endif
  4395. }
  4396. catch (Exception)
  4397. {
  4398. #if DEBUG
  4399. Exception ex = new Exception("Failed to shutdown socket for " + this.name ?? this.ip, e);
  4400. Server.ErrorLog(ex);
  4401. #endif
  4402. }
  4403. try
  4404. {
  4405. socket.Close();
  4406. #if DEBUG
  4407. Server.s.Log("Socket was closed for " + this.name ?? this.ip);
  4408. #endif
  4409. }
  4410. catch (Exception)
  4411. {
  4412. #if DEBUG
  4413. Exception ex = new Exception("Failed to close socket for " + this.name ?? this.ip, e);
  4414. Server.ErrorLog(ex);
  4415. #endif
  4416. }
  4417. }
  4418. public void leftGame(string kickString = "", bool skip = false)
  4419. {
  4420. OnPlayerDisconnectEvent.Call(this, kickString);
  4421. //Umm...fixed?
  4422. if (name == "")
  4423. {
  4424. if (socket != null)
  4425. CloseSocket();
  4426. if (connections.Contains(this))
  4427. connections.Remove(this);
  4428. SaveUndo();
  4429. disconnected = true;
  4430. return;
  4431. }
  4432. ////If player has been found in the reviewlist he will be removed
  4433. bool leavetest = false;
  4434. foreach (string testwho2 in Server.reviewlist)
  4435. {
  4436. if (testwho2 == name)
  4437. {
  4438. leavetest = true;
  4439. }
  4440. }
  4441. if (leavetest)
  4442. {
  4443. Server.reviewlist.Remove(name);
  4444. }
  4445. try
  4446. {
  4447. if (disconnected)
  4448. {
  4449. this.CloseSocket();
  4450. if (connections.Contains(this))
  4451. connections.Remove(this);
  4452. return;
  4453. }
  4454. // FlyBuffer.Clear();
  4455. disconnected = true;
  4456. pingTimer.Stop();
  4457. pingTimer.Dispose();
  4458. if (File.Exists("ranks/ignore/" + this.name + ".txt"))
  4459. {
  4460. try
  4461. {
  4462. File.WriteAllLines("ranks/ignore/" + this.name + ".txt", this.listignored.ToArray());
  4463. }
  4464. catch
  4465. {
  4466. Server.s.Log("Failed to save ignored list for player: " + this.name);
  4467. }
  4468. }
  4469. if (File.Exists("ranks/ignore/GlobalIgnore.xml"))
  4470. {
  4471. try
  4472. {
  4473. File.WriteAllLines("ranks/ignore/GlobalIgnore.xml", globalignores.ToArray());
  4474. }
  4475. catch
  4476. {
  4477. Server.s.Log("failed to save global ignore list!");
  4478. }
  4479. }
  4480. afkTimer.Stop();
  4481. afkTimer.Dispose();
  4482. muteTimer.Stop();
  4483. muteTimer.Dispose();
  4484. timespent.Stop();
  4485. timespent.Dispose();
  4486. afkCount = 0;
  4487. afkStart = DateTime.Now;
  4488. if (Server.afkset.Contains(name)) Server.afkset.Remove(name);
  4489. if (kickString == "") kickString = "Disconnected.";
  4490. SendKick(kickString);
  4491. if (loggedIn)
  4492. {
  4493. isFlying = false;
  4494. aiming = false;
  4495. if (CountdownGame.players.Contains(this))
  4496. {
  4497. if (CountdownGame.playersleftlist.Contains(this))
  4498. {
  4499. CountdownGame.PlayerLeft(this);
  4500. }
  4501. CountdownGame.players.Remove(this);
  4502. }
  4503. TntWarsGame tntwarsgame = TntWarsGame.GetTntWarsGame(this);
  4504. if (tntwarsgame != null)
  4505. {
  4506. tntwarsgame.Players.Remove(tntwarsgame.FindPlayer(this));
  4507. tntwarsgame.SendAllPlayersMessage("TNT Wars: " + color + name + Server.DefaultColor + " has left TNT Wars!");
  4508. }
  4509. GlobalDie(this, false);
  4510. if (kickString == "Disconnected." || kickString.IndexOf("Server shutdown") != -1 || kickString == Server.customShutdownMessage)
  4511. {
  4512. if (!Directory.Exists("text/logout"))
  4513. {
  4514. Directory.CreateDirectory("text/logout");
  4515. }
  4516. if (!File.Exists("text/logout/" + name + ".txt"))
  4517. {
  4518. File.WriteAllText("text/logout/" + name + ".txt", "Disconnected.");
  4519. }
  4520. if (!hidden)
  4521. {
  4522. string leavem = "&c- " + color + prefix + name + Server.DefaultColor + " " + File.ReadAllText("text/logout/" + name + ".txt");
  4523. if ((Server.guestLeaveNotify && this.group.Permission <= LevelPermission.Guest) || this.group.Permission > LevelPermission.Guest)
  4524. {
  4525. Player.players.ForEach(delegate(Player p1)
  4526. {
  4527. if (p1.UsingWom)
  4528. {
  4529. byte[] buffer = new byte[65];
  4530. Player.StringFormat("^detail.user.part=" + color + name + c.white, 64).CopyTo(buffer, 1);
  4531. p1.SendRaw(13, buffer);
  4532. buffer = null;
  4533. }
  4534. else
  4535. Player.SendMessage(p1, leavem);
  4536. });
  4537. }
  4538. }
  4539. //IRCBot.Say(name + " left the game.");
  4540. Server.s.Log(name + " disconnected.");
  4541. }
  4542. else
  4543. {
  4544. totalKicked++;
  4545. GlobalChat(this, "&c- " + color + prefix + name + Server.DefaultColor + " kicked (" + kickString + Server.DefaultColor + ").", false);
  4546. //IRCBot.Say(name + " kicked (" + kickString + ").");
  4547. Server.s.Log(name + " kicked (" + kickString + ").");
  4548. }
  4549. try { save(); }
  4550. catch (Exception e) { Server.ErrorLog(e); }
  4551. players.Remove(this);
  4552. players.ForEach(delegate(Player p)
  4553. {
  4554. if (p != this && extension)
  4555. {
  4556. p.SendExtRemovePlayerName(this.id);
  4557. }
  4558. });
  4559. Server.s.PlayerListUpdate();
  4560. try
  4561. {
  4562. left.Add(this.name.ToLower(), this.ip);
  4563. }
  4564. catch (Exception)
  4565. {
  4566. //Server.ErrorLog(e);
  4567. }
  4568. /*if (Server.AutoLoad && level.unload)
  4569. {
  4570. foreach (Player pl in Player.players)
  4571. if (pl.level == level) hasplayers = true;
  4572. if (!level.name.Contains("Museum " + Server.DefaultColor) && hasplayers == false)
  4573. {
  4574. level.Unload();
  4575. }
  4576. }*/
  4577. if (Server.AutoLoad && level.unload && !level.name.Contains("Museum " + Server.DefaultColor) && IsAloneOnCurrentLevel())
  4578. level.Unload(true);
  4579. if (PlayerDisconnect != null)
  4580. PlayerDisconnect(this, kickString);
  4581. this.Dispose();
  4582. }
  4583. else
  4584. {
  4585. connections.Remove(this);
  4586. Server.s.Log(ip + " disconnected.");
  4587. }
  4588. if (Server.zombie.GameInProgess())
  4589. {
  4590. try
  4591. {
  4592. ZombieGame.infectd.Remove(this);
  4593. ZombieGame.alive.Remove(this);
  4594. }
  4595. catch { }
  4596. }
  4597. Server.zombie.InfectedPlayerDC();
  4598. }
  4599. catch (Exception e) { Server.ErrorLog(e); }
  4600. finally
  4601. {
  4602. CloseSocket();
  4603. }
  4604. }
  4605. public void SaveUndo()
  4606. {
  4607. SaveUndo(this);
  4608. }
  4609. public static void SaveUndo(Player p)
  4610. {
  4611. if (p == null || p.UndoBuffer == null || p.UndoBuffer.Count < 1) return;
  4612. try
  4613. {
  4614. if (!Directory.Exists("extra/undo")) Directory.CreateDirectory("extra/undo");
  4615. if (!Directory.Exists("extra/undoPrevious")) Directory.CreateDirectory("extra/undoPrevious");
  4616. DirectoryInfo di = new DirectoryInfo("extra/undo");
  4617. if (di.GetDirectories("*").Length >= Server.totalUndo)
  4618. {
  4619. Directory.Delete("extra/undoPrevious", true);
  4620. Directory.Move("extra/undo", "extra/undoPrevious");
  4621. Directory.CreateDirectory("extra/undo");
  4622. }
  4623. if (!Directory.Exists("extra/undo/" + p.name.ToLower())) Directory.CreateDirectory("extra/undo/" + p.name.ToLower());
  4624. di = new DirectoryInfo("extra/undo/" + p.name.ToLower());
  4625. int number = di.GetFiles("*.undo").Length;
  4626. File.Create("extra/undo/" + p.name.ToLower() + "/" + number + ".undo").Dispose();
  4627. using (StreamWriter w = File.CreateText("extra/undo/" + p.name.ToLower() + "/" + number + ".undo"))
  4628. {
  4629. foreach (UndoPos uP in p.UndoBuffer.ToList())
  4630. {
  4631. w.Write(uP.mapName + " " +
  4632. uP.x + " " + uP.y + " " + uP.z + " " +
  4633. uP.timePlaced.ToString(CultureInfo.InvariantCulture).Replace(' ', '&') + " " +
  4634. uP.type + " " + uP.newtype + " ");
  4635. }
  4636. }
  4637. }
  4638. catch (Exception e) { Server.s.Log("Error saving undo data for " + p.name + "!"); Server.ErrorLog(e); }
  4639. }
  4640. public void Dispose()
  4641. {
  4642. //throw new NotImplementedException();
  4643. if (connections.Contains(this)) connections.Remove(this);
  4644. Extras.Clear();
  4645. CopyBuffer.Clear();
  4646. RedoBuffer.Clear();
  4647. UndoBuffer.Clear();
  4648. spamBlockLog.Clear();
  4649. //spamChatLog.Clear();
  4650. spyChatRooms.Clear();
  4651. /*try
  4652. {
  4653. //this.commThread.Abort();
  4654. }
  4655. catch { }*/
  4656. }
  4657. //fixed undo code
  4658. public bool IsAloneOnCurrentLevel()
  4659. {
  4660. return players.All(pl => pl.level != level || pl == this);
  4661. }
  4662. #endregion
  4663. #region == CHECKING ==
  4664. public static List<Player> GetPlayers() { return new List<Player>(players); }
  4665. public static bool Exists(string name)
  4666. {
  4667. foreach (Player p in players) { if (p.name.ToLower() == name.ToLower()) { return true; } } return false;
  4668. }
  4669. public static bool Exists(byte id)
  4670. {
  4671. foreach (Player p in players) { if (p.id == id) { return true; } } return false;
  4672. }
  4673. public static Player Find(string name)
  4674. {
  4675. List<Player> tempList = new List<Player>();
  4676. tempList.AddRange(players);
  4677. Player tempPlayer = null; bool returnNull = false;
  4678. foreach (Player p in tempList)
  4679. {
  4680. if (p.name.ToLower() == name.ToLower()) return p;
  4681. if (p.name.ToLower().IndexOf(name.ToLower()) != -1)
  4682. {
  4683. if (tempPlayer == null) tempPlayer = p;
  4684. else returnNull = true;
  4685. }
  4686. }
  4687. if (returnNull == true) return null;
  4688. if (tempPlayer != null) return tempPlayer;
  4689. return null;
  4690. }
  4691. public static Group GetGroup(string name)
  4692. {
  4693. return Group.findPlayerGroup(name);
  4694. }
  4695. public static string GetColor(string name)
  4696. {
  4697. return GetGroup(name).color;
  4698. }
  4699. public static OfflinePlayer FindOffline(string name)
  4700. {
  4701. OfflinePlayer offPlayer = new OfflinePlayer("", "", "", "", 0);
  4702. Database.AddParams("@Name", name);
  4703. using (DataTable playerDB = Database.fillData("SELECT * FROM Players WHERE Name = @Name"))
  4704. {
  4705. if (playerDB.Rows.Count == 0)
  4706. return offPlayer;
  4707. else
  4708. {
  4709. offPlayer.name = playerDB.Rows[0]["Name"].ToString().Trim();
  4710. offPlayer.title = playerDB.Rows[0]["Title"].ToString().Trim();
  4711. offPlayer.titleColor = c.Parse(playerDB.Rows[0]["title_color"].ToString().Trim());
  4712. offPlayer.color = c.Parse(playerDB.Rows[0]["color"].ToString().Trim());
  4713. offPlayer.money = int.Parse(playerDB.Rows[0]["Money"].ToString());
  4714. if (offPlayer.color == "") { offPlayer.color = GetGroup(offPlayer.name).color; }
  4715. }
  4716. }
  4717. return offPlayer;
  4718. }
  4719. #endregion
  4720. #region == OTHER ==
  4721. static byte FreeId()
  4722. {
  4723. /*
  4724. for (byte i = 0; i < 255; i++)
  4725. {
  4726. foreach (Player p in players)
  4727. {
  4728. if (p.id == i) { goto Next; }
  4729. } return i;
  4730. Next: continue;
  4731. } unchecked { return (byte)-1; }*/
  4732. for (byte i = 0; i < Block.maxblocks; i++)
  4733. {
  4734. bool used = players.Any(p => p.id == i);
  4735. if (!used)
  4736. return i;
  4737. }
  4738. return (byte)1;
  4739. }
  4740. public static byte[] StringFormat(string str, int size)
  4741. {
  4742. byte[] bytes = new byte[size];
  4743. bytes = enc.GetBytes(str.PadRight(size).Substring(0, size));
  4744. return bytes;
  4745. }
  4746. // TODO: Optimize this using a StringBuilder
  4747. static List<string> Wordwrap(string message)
  4748. {
  4749. List<string> lines = new List<string>();
  4750. message = Regex.Replace(message, @"(&[0-9a-f])+(&[0-9a-f])", "$2");
  4751. message = Regex.Replace(message, @"(&[0-9a-f])+$", "");
  4752. int limit = 64; string color = "";
  4753. while (message.Length > 0)
  4754. {
  4755. //if (Regex.IsMatch(message, "&a")) break;
  4756. if (lines.Count > 0)
  4757. {
  4758. if (message[0].ToString() == "&")
  4759. message = "> " + message.Trim();
  4760. else
  4761. message = "> " + color + message.Trim();
  4762. }
  4763. if (message.IndexOf("&") == message.IndexOf("&", message.IndexOf("&") + 1) - 2)
  4764. message = message.Remove(message.IndexOf("&"), 2);
  4765. if (message.Length <= limit) { lines.Add(message); break; }
  4766. for (int i = limit - 1; i > limit - 20; --i)
  4767. if (message[i] == ' ')
  4768. {
  4769. lines.Add(message.Substring(0, i));
  4770. goto Next;
  4771. }
  4772. retry:
  4773. if (message.Length == 0 || limit == 0) { return lines; }
  4774. try
  4775. {
  4776. if (message.Substring(limit - 2, 1) == "&" || message.Substring(limit - 1, 1) == "&")
  4777. {
  4778. message = message.Remove(limit - 2, 1);
  4779. limit -= 2;
  4780. goto retry;
  4781. }
  4782. else if (message[limit - 1] < 32 || message[limit - 1] > 127)
  4783. {
  4784. message = message.Remove(limit - 1, 1);
  4785. limit -= 1;
  4786. //goto retry;
  4787. }
  4788. }
  4789. catch { return lines; }
  4790. lines.Add(message.Substring(0, limit));
  4791. Next: message = message.Substring(lines[lines.Count - 1].Length);
  4792. if (lines.Count == 1) limit = 60;
  4793. int index = lines[lines.Count - 1].LastIndexOf('&');
  4794. if (index != -1)
  4795. {
  4796. if (index < lines[lines.Count - 1].Length - 1)
  4797. {
  4798. char next = lines[lines.Count - 1][index + 1];
  4799. if ("0123456789abcdef".IndexOf(next) != -1) { color = "&" + next; }
  4800. if (index == lines[lines.Count - 1].Length - 1)
  4801. {
  4802. lines[lines.Count - 1] = lines[lines.Count - 1].Substring(0, lines[lines.Count - 1].Length - 2);
  4803. }
  4804. }
  4805. else if (message.Length != 0)
  4806. {
  4807. char next = message[0];
  4808. if ("0123456789abcdef".IndexOf(next) != -1)
  4809. {
  4810. color = "&" + next;
  4811. }
  4812. lines[lines.Count - 1] = lines[lines.Count - 1].Substring(0, lines[lines.Count - 1].Length - 1);
  4813. message = message.Substring(1);
  4814. }
  4815. }
  4816. }
  4817. char[] temp;
  4818. for (int i = 0; i < lines.Count; i++) // Gotta do it the old fashioned way...
  4819. {
  4820. temp = lines[i].ToCharArray();
  4821. if (temp[temp.Length - 2] == '%' || temp[temp.Length - 2] == '&')
  4822. {
  4823. temp[temp.Length - 1] = ' ';
  4824. temp[temp.Length - 2] = ' ';
  4825. }
  4826. StringBuilder message1 = new StringBuilder();
  4827. message1.Append(temp);
  4828. lines[i] = message1.ToString();
  4829. }
  4830. return lines;
  4831. }
  4832. public static bool ValidName(string name, Player p = null)
  4833. {
  4834. string allowedchars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890._@+";
  4835. if (p != null && p.Mojangaccount) allowedchars += "-";
  4836. return name.All(ch => allowedchars.IndexOf(ch) != -1);
  4837. }
  4838. public static int GetBannedCount()
  4839. {
  4840. try
  4841. {
  4842. return File.ReadAllLines("ranks/banned.txt").Length;
  4843. }
  4844. catch/* (Exception ex)*/
  4845. {
  4846. return 0;
  4847. }
  4848. }
  4849. public static bool CommandProtected(string cmd, string message)
  4850. {
  4851. string foundName = "";
  4852. Player who = null;
  4853. bool self = false;
  4854. if (Server.ProtectOver.Contains(cmd))
  4855. switch (cmd)
  4856. {
  4857. //case "demote":
  4858. case "freeze":
  4859. case "impersonate":
  4860. //case "kick":
  4861. case "kickban":
  4862. case "mute":
  4863. case "possess":
  4864. //case "promote":
  4865. case "sendcmd":
  4866. case "tempban":
  4867. case "uban":
  4868. case "voice":
  4869. case "xban":
  4870. //case "unban":
  4871. //case "xundo":
  4872. if (message.Split().Length > 0)
  4873. {
  4874. who = Find(message.Split()[0]);
  4875. foundName = who != null ? who.name : message.Split()[0];
  4876. }
  4877. break;
  4878. /*case "banip": //this one is hard coded into CmdBanip.cs
  4879. break;*/
  4880. case "ban":
  4881. case "joker":
  4882. if (message.Split().Length > 0)
  4883. {
  4884. try
  4885. {
  4886. who = message.StartsWith("@") || message.StartsWith("#") ? Find(message.Split()[0].Substring(1)) : Find(message.Split()[0]);
  4887. }
  4888. catch (ArgumentOutOfRangeException) { who = null; }
  4889. foundName = who != null ? who.name : message.Split()[0];
  4890. }
  4891. break;
  4892. case "lockdown":
  4893. if (message.Split().Length > 1 && message.Split()[0].ToLower() == "player")
  4894. {
  4895. who = Find(message.Split()[1]);
  4896. foundName = who != null ? who.name : message.Split()[1];
  4897. }
  4898. break;
  4899. case "jail":
  4900. if (message.Split().Length > 0 && message.Split()[0].ToLower() != "set")
  4901. {
  4902. who = Find(message.Split()[0]);
  4903. foundName = who != null ? who.name : message.Split()[0];
  4904. }
  4905. break;
  4906. case "ignore":
  4907. List<string> badlist = new List<string>();
  4908. badlist.Add("all"); badlist.Add("global"); badlist.Add("list");
  4909. if (message.Split().Length > 0 && badlist.Contains(message.Split()[0].ToLower()))
  4910. {
  4911. who = Find(message.Split()[0]);
  4912. foundName = who != null ? who.name : message.Split()[0];
  4913. }
  4914. badlist = null;
  4915. break;
  4916. default:
  4917. break;
  4918. }
  4919. foundName = foundName.ToLower();
  4920. if (who != null && foundName == who.name.ToLower()) { self = true; }
  4921. try
  4922. {
  4923. if (Server.forgeProtection == ForgeProtection.Mod)
  4924. return (Server.Mods.Contains(foundName) || Server.Devs.Contains(foundName)) && !self;
  4925. if (Server.forgeProtection == ForgeProtection.Dev)
  4926. return Server.Devs.Contains(foundName) && !self;
  4927. }
  4928. catch { }
  4929. return false;
  4930. }
  4931. #endregion
  4932. #region == Host <> Network ==
  4933. public static byte[] HTNO(ushort x)
  4934. {
  4935. byte[] y = BitConverter.GetBytes(x); Array.Reverse(y); return y;
  4936. }
  4937. public static ushort NTHO(byte[] x, int offset)
  4938. {
  4939. byte[] y = new byte[2];
  4940. Buffer.BlockCopy(x, offset, y, 0, 2); Array.Reverse(y);
  4941. return BitConverter.ToUInt16(y, 0);
  4942. }
  4943. public static byte[] HTNO(short x)
  4944. {
  4945. byte[] y = BitConverter.GetBytes(x); Array.Reverse(y); return y;
  4946. }
  4947. #endregion
  4948. bool CheckBlockSpam()
  4949. {
  4950. if (spamBlockLog.Count >= spamBlockCount)
  4951. {
  4952. DateTime oldestTime = spamBlockLog.Dequeue();
  4953. double spamTimer = DateTime.Now.Subtract(oldestTime).TotalSeconds;
  4954. if (spamTimer < spamBlockTimer && !ignoreGrief)
  4955. {
  4956. this.Kick("You were kicked by antigrief system. Slow down.");
  4957. SendMessage(c.red + name + " was kicked for suspected griefing.");
  4958. Server.s.Log(name + " was kicked for block spam (" + spamBlockCount + " blocks in " + spamTimer + " seconds)");
  4959. return true;
  4960. }
  4961. }
  4962. spamBlockLog.Enqueue(DateTime.Now);
  4963. return false;
  4964. }
  4965. #region getters
  4966. public ushort[] footLocation
  4967. {
  4968. get
  4969. {
  4970. return getLoc(false);
  4971. }
  4972. }
  4973. public ushort[] headLocation
  4974. {
  4975. get
  4976. {
  4977. return getLoc(true);
  4978. }
  4979. }
  4980. public ushort[] getLoc(bool head)
  4981. {
  4982. ushort[] myPos = pos;
  4983. myPos[0] /= 32;
  4984. if (head) myPos[1] = (ushort)((myPos[1] + 4) / 32);
  4985. else myPos[1] = (ushort)((myPos[1] + 4) / 32 - 1);
  4986. myPos[2] /= 32;
  4987. return myPos;
  4988. }
  4989. public void setLoc(ushort[] myPos)
  4990. {
  4991. myPos[0] *= 32;
  4992. myPos[1] *= 32;
  4993. myPos[2] *= 32;
  4994. unchecked { SendPos((byte)-1, myPos[0], myPos[1], myPos[2], rot[0], rot[1]); }
  4995. }
  4996. #endregion
  4997. public static bool IPInPrivateRange(string ip)
  4998. {
  4999. //range of 172.16.0.0 - 172.31.255.255
  5000. if (ip.StartsWith("172.") && (int.Parse(ip.Split('.')[1]) >= 16 && int.Parse(ip.Split('.')[1]) <= 31))
  5001. return true;
  5002. return IPAddress.IsLoopback(IPAddress.Parse(ip)) || ip.StartsWith("192.168.") || ip.StartsWith("10.");
  5003. //return IsLocalIpAddress(ip);
  5004. }
  5005. public string ResolveExternalIP(string ip)
  5006. {
  5007. HTTPGet req = new HTTPGet();
  5008. req.Request("http://checkip.dyndns.org");
  5009. string[] a1 = req.ResponseBody.Split(':');
  5010. string a2 = a1[1].Substring(1);
  5011. string[] a3 = a2.Split('<');
  5012. return a3[0];
  5013. }
  5014. public static bool IsLocalIpAddress(string host)
  5015. {
  5016. try
  5017. { // get host IP addresses
  5018. IPAddress[] hostIPs = Dns.GetHostAddresses(host);
  5019. // get local IP addresses
  5020. IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());
  5021. // test if any host IP equals to any local IP or to localhost
  5022. foreach (IPAddress hostIP in hostIPs)
  5023. {
  5024. // is localhost
  5025. if (IPAddress.IsLoopback(hostIP)) return true;
  5026. // is local address
  5027. foreach (IPAddress localIP in localIPs)
  5028. {
  5029. if (hostIP.Equals(localIP)) return true;
  5030. }
  5031. }
  5032. }
  5033. catch { }
  5034. return false;
  5035. }
  5036. public class Waypoint
  5037. {
  5038. public class WP
  5039. {
  5040. public ushort x;
  5041. public ushort y;
  5042. public ushort z;
  5043. public byte rotx;
  5044. public byte roty;
  5045. public string name;
  5046. public string lvlname;
  5047. }
  5048. public static WP Find(string name, Player p)
  5049. {
  5050. WP wpfound = null;
  5051. bool found = false;
  5052. foreach (WP wp in p.Waypoints)
  5053. {
  5054. if (wp.name.ToLower() == name.ToLower())
  5055. {
  5056. wpfound = wp;
  5057. found = true;
  5058. }
  5059. }
  5060. if (found) { return wpfound; }
  5061. else { return null; }
  5062. }
  5063. public static void Goto(string waypoint, Player p)
  5064. {
  5065. if (!Exists(waypoint, p)) return;
  5066. WP wp = Find(waypoint, p);
  5067. Level lvl = Level.Find(wp.lvlname);
  5068. if (wp == null) return;
  5069. if (lvl != null)
  5070. {
  5071. if (p.level != lvl)
  5072. {
  5073. Command.all.Find("goto").Use(p, lvl.name);
  5074. while (p.Loading) { Thread.Sleep(250); }
  5075. }
  5076. unchecked { p.SendPos((byte)-1, wp.x, wp.y, wp.z, wp.rotx, wp.roty); }
  5077. Player.SendMessage(p, "Sent you to waypoint");
  5078. }
  5079. else { Player.SendMessage(p, "The map that that waypoint is on isn't loaded right now (" + wp.lvlname + ")"); return; }
  5080. }
  5081. public static void Create(string waypoint, Player p)
  5082. {
  5083. Player.Waypoint.WP wp = new Player.Waypoint.WP();
  5084. {
  5085. wp.x = p.pos[0];
  5086. wp.y = p.pos[1];
  5087. wp.z = p.pos[2];
  5088. wp.rotx = p.rot[0];
  5089. wp.roty = p.rot[1];
  5090. wp.name = waypoint;
  5091. wp.lvlname = p.level.name;
  5092. }
  5093. p.Waypoints.Add(wp);
  5094. Save();
  5095. }
  5096. public static void Update(string waypoint, Player p)
  5097. {
  5098. WP wp = Find(waypoint, p);
  5099. p.Waypoints.Remove(wp);
  5100. {
  5101. wp.x = p.pos[0];
  5102. wp.y = p.pos[1];
  5103. wp.z = p.pos[2];
  5104. wp.rotx = p.rot[0];
  5105. wp.roty = p.rot[1];
  5106. wp.name = waypoint;
  5107. wp.lvlname = p.level.name;
  5108. }
  5109. p.Waypoints.Add(wp);
  5110. Save();
  5111. }
  5112. public static void Remove(string waypoint, Player p)
  5113. {
  5114. WP wp = Find(waypoint, p);
  5115. p.Waypoints.Remove(wp);
  5116. Save();
  5117. }
  5118. public static bool Exists(string waypoint, Player p)
  5119. {
  5120. bool exists = false;
  5121. foreach (WP wp in p.Waypoints)
  5122. {
  5123. if (wp.name.ToLower() == waypoint.ToLower())
  5124. {
  5125. exists = true;
  5126. }
  5127. }
  5128. return exists;
  5129. }
  5130. public static void Load(Player p)
  5131. {
  5132. if (File.Exists("extra/Waypoints/" + p.name + ".save"))
  5133. {
  5134. using (StreamReader SR = new StreamReader("extra/Waypoints/" + p.name + ".save"))
  5135. {
  5136. bool failed = false;
  5137. string line;
  5138. while (SR.EndOfStream == false)
  5139. {
  5140. line = SR.ReadLine().ToLower().Trim();
  5141. if (!line.StartsWith("#") && line.Contains(":"))
  5142. {
  5143. failed = false;
  5144. string[] LINE = line.ToLower().Split(':');
  5145. WP wp = new WP();
  5146. try
  5147. {
  5148. wp.name = LINE[0];
  5149. wp.lvlname = LINE[1];
  5150. wp.x = ushort.Parse(LINE[2]);
  5151. wp.y = ushort.Parse(LINE[3]);
  5152. wp.z = ushort.Parse(LINE[4]);
  5153. wp.rotx = byte.Parse(LINE[5]);
  5154. wp.roty = byte.Parse(LINE[6]);
  5155. }
  5156. catch
  5157. {
  5158. Server.s.Log("Couldn't load a Waypoint!");
  5159. failed = true;
  5160. }
  5161. if (failed == false)
  5162. {
  5163. p.Waypoints.Add(wp);
  5164. }
  5165. }
  5166. }
  5167. SR.Dispose();
  5168. }
  5169. }
  5170. }
  5171. public static void Save()
  5172. {
  5173. foreach (Player p in Player.players)
  5174. {
  5175. if (p.Waypoints.Count >= 1)
  5176. {
  5177. using (StreamWriter SW = new StreamWriter("extra/Waypoints/" + p.name + ".save"))
  5178. {
  5179. foreach (WP wp in p.Waypoints)
  5180. {
  5181. SW.WriteLine(wp.name + ":" + wp.lvlname + ":" + wp.x + ":" + wp.y + ":" + wp.z + ":" + wp.rotx + ":" + wp.roty);
  5182. }
  5183. SW.Dispose();
  5184. }
  5185. }
  5186. }
  5187. }
  5188. }
  5189. public bool EnoughMoney(int amount)
  5190. {
  5191. if (this.money >= amount)
  5192. return true;
  5193. return false;
  5194. }
  5195. public void ReviewTimer()
  5196. {
  5197. this.canusereview = false;
  5198. System.Timers.Timer Clock = new System.Timers.Timer(1000 * Server.reviewcooldown);
  5199. Clock.Elapsed += delegate { this.canusereview = true; Clock.Dispose(); };
  5200. Clock.Start();
  5201. }
  5202. public void TntAtATime()
  5203. {
  5204. new Thread(() =>
  5205. {
  5206. CurrentAmountOfTnt += 1;
  5207. switch (TntWarsGame.GetTntWarsGame(this).GameDifficulty)
  5208. {
  5209. case TntWarsGame.TntWarsDifficulty.Easy:
  5210. Thread.Sleep(3250);
  5211. break;
  5212. case TntWarsGame.TntWarsDifficulty.Normal:
  5213. Thread.Sleep(2250);
  5214. break;
  5215. case TntWarsGame.TntWarsDifficulty.Hard:
  5216. case TntWarsGame.TntWarsDifficulty.Extreme:
  5217. Thread.Sleep(1250);
  5218. break;
  5219. }
  5220. CurrentAmountOfTnt -= 1;
  5221. }).Start();
  5222. }
  5223. public string ReadString(int count = 64)
  5224. {
  5225. if (Reader == null) return null;
  5226. var chars = new byte[count];
  5227. Reader.Read(chars, 0, count);
  5228. return Encoding.UTF8.GetString(chars).TrimEnd().Replace("\0", string.Empty);
  5229. }
  5230. }
  5231. }