PageRenderTime 28ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/ChatLineBreaker/src/pemapmodder/clb/Old.php

https://gitlab.com/Skull3x/Small-ZC-Plugins
PHP | 308 lines | 281 code | 21 blank | 6 comment | 34 complexity | daaf0df87f14f7dcb525f6efced56dec MD5 | raw file
  1. <?php
  2. namespace pemapmodder\clb;
  3. use pocketmine\event\Listener;
  4. use pocketmine\event\player\PlayerCommandPreprocessEvent;
  5. use pocketmine\event\server\DataPacketSendEvent;
  6. use pocketmine\network\protocol\MessagePacket;
  7. use pocketmine\Player;
  8. use pocketmine\plugin\PluginBase;
  9. use pocketmine\utils\Binary;
  10. class ChatLineBreaker extends PluginBase implements Listener{
  11. const MAGIC_PREFIX = "\x00\xffCLBDB>";
  12. const MAGIC_SUFFIX = "=CLBDB\xff\x00";
  13. const CORRUPTION_PREFIX = "prefix";
  14. const CORRUPTION_SUFFIX = "suffix";
  15. const CORRUPTION_API = "unsupported api";
  16. const CURRENT_VERSION = "\x01";
  17. const INITIAL_RELEASE = "";
  18. const DB_LANG_UPDATE = "\x01";
  19. public $database = [];
  20. public $testing = [];
  21. public $config; // made them public to thank the public Player::$data :)
  22. public $path, $cfgPath, $langPath;
  23. /** @var Lang */
  24. public $lang;
  25. public function onEnable(){
  26. $time = microtime(true);
  27. echo ".";
  28. $this->path = $this->getDataFolder() . "players.dat";
  29. $this->cfgPath = $this->getDataFolder() . "config.";
  30. $this->saveDefaultConfig();
  31. $this->langPath = $this->getDataFolder() . "texts.lang";
  32. $this->lang = new Lang($this->langPath);
  33. echo ".";
  34. $this->load();
  35. $time *= -1;
  36. $time += microtime(true);
  37. $time *= 1000;
  38. echo " Done! ($time ms)" . PHP_EOL;
  39. }
  40. public function eventSetLength($data){
  41. if(!isset($data["cid"]) or !isset($data["length"])){
  42. return false;
  43. }
  44. $this->setLength($data["cid"], $data["length"]);
  45. return true;
  46. }
  47. public function eventSetEnabled($data){
  48. if(!isset($data["cid"]) or !isset($data["bool"])){
  49. return false;
  50. }
  51. $this->setEnabled($data["cid"], $data["bool"]);
  52. return true;
  53. }
  54. public function onChat(PlayerCommandPreprocessEvent $event){
  55. $p = $event->getPlayer();
  56. if(!in_array($p->getID(), $this->testing)){
  57. return;
  58. }
  59. $msg = $event->getMessage();
  60. $cid = $p->loginData["clientId"];
  61. if(!is_numeric($msg)){
  62. $p->sendMessage($this->lang["calibrate.response.not.numeric"]);
  63. $event->setCancelled();
  64. return;
  65. }
  66. $l = (int) $msg;
  67. $issuer = $p; // such a lazy fix... :P
  68. if($l <= 5){
  69. $issuer->sendMessage(str_replace("@char", "$l", $this->lang["calibrate.response.too.low"]));
  70. $event->setCancelled();
  71. return;
  72. }
  73. if($l >= 0b10000000){
  74. $issuer->sendMessage(str_replace("@char", "$l", $this->lang["calibrate.response.too.high"]));
  75. $event->setCancelled();
  76. return;
  77. }
  78. $this->setLength($cid, $l);
  79. $p->sendMessage(str_replace("@char", "$l", $this->lang["calibrate.response.succeed"]));
  80. unset($this->testing[array_search($p->getID(), $this->testing)]);
  81. $event->setCancelled();
  82. return;
  83. }
  84. public function onQuit($p){
  85. if(in_array($p->CID, $this->testing)){
  86. unset($this->testing[array_search($p->CID, $this->testing)]);
  87. }
  88. }
  89. public function onSend(DataPacketSendEvent $evt){
  90. if(!(($pk = $evt->getPacket()) instanceof MessagePacket)){
  91. return;
  92. }
  93. if($evt->getPacket()->source === "clb.followup.linebreak"){
  94. $evt->getPacket()->source = "";
  95. return;
  96. }
  97. $packets = $this->processMessage($evt->getPlayer()->data->get("lastID"), $pk->message, $evt->getPlayer()); // thanks for making it public property, shoghicp!
  98. if($packets === false){
  99. return;
  100. }
  101. // I made it use client ID because the line break length should depend on the device not the player or IP
  102. $evt->setCancelled(true);
  103. foreach($packets as $pk){
  104. $evt->getPlayer()->dataPacket($pk);
  105. }
  106. if(defined("DEBUG") and DEBUG >= 2){
  107. // var_export($pk);
  108. }
  109. }
  110. public function onCmd($cmd, $args, $issuer){
  111. if($issuer === "console"){
  112. return $this->lang["cmd.console.reject"]; // lol
  113. }
  114. if($issuer === "rcon"){
  115. return "Did you expect we can modify your RCon client preferences for you? We are not hackers!"; // lol * 2
  116. }
  117. $cmd = array_shift($args);
  118. $output = "[CLB] ";
  119. $cid = $issuer->data->get("lastID");
  120. switch($cmd){
  121. case "cal":
  122. case "calibrate":
  123. $msgs = $this->getTesterMessage();
  124. $output .= array_shift($msgs);
  125. foreach($msgs as $key => $value){
  126. $this->api->schedule(40 * ($key + 1), [$issuer, "sendChat"], $value, false, "ChatLineBreaker"); // why did you add this 5th arg...
  127. }
  128. $this->testing[] = $issuer->CID;
  129. break;
  130. case "set":
  131. $l = (int) array_shift($args);
  132. if($l <= 5){
  133. $output .= $this->lang["calibrate.response.not.numeric"] . "\n";
  134. break;
  135. }
  136. if($l >= 0b10000000){
  137. $output .= str_replace("@char", "$l", $this->lang["calibrate.response.too.low"]) . "\n";
  138. break;
  139. }
  140. $this->setLength($cid, $l);
  141. $output .= "Your CLB length is now $l.\n";
  142. break;
  143. case "check":
  144. case "view":
  145. $l = $this->getLength($cid);
  146. $output .= $this->lang["view." . ($this->isEnabled($cid) ? "on" : "off")];
  147. $output .= str_replace("@length", "$l", $this->lang["view.length"]);
  148. break;
  149. case "tog":
  150. case "toggle":
  151. $this->setEnabled($cid, ($b = !$this->isEnabled($cid)));
  152. $output .= $this->lang["toggle." . ($b ? "on" : "off")];
  153. break;
  154. case "help":
  155. $output .= "Showing help for /clb\n";
  156. default:
  157. $output .= "\"/clb\" ChatLineBreaker (CLB) settings panel.\n";
  158. $output .= "CLB is a tool for breaking chat lines into pieces automatically to suit your device length.\n";
  159. $output .= "\"/clb cal\" or \"/clb calibrate\": Use the CLB linebreak tester to calibrate your CLB length.\n";
  160. $output .= "\"/clb set <length>\": (Not recommended) Set your CLB length to the defined length.\n";
  161. $output .= "\"/clb view\" or \"/clb check\" to check if CLB is enabled for you.\n";
  162. $output .= "\"/clb tog\" or \"/clb toggle\" to toggle your CLB.\n";
  163. }
  164. if(defined("DEBUG") and DEBUG >= 2){
  165. var_export($output);
  166. }
  167. return $output;
  168. }
  169. public function getLength($cid){
  170. if(isset($this->database[$cid])){
  171. return $this->database[$cid][1];
  172. }
  173. return $this->config->get("default-length");
  174. }
  175. public function setLength($cid, $length){
  176. $this->database[$cid] = [$this->isEnabled($cid), $length];
  177. }
  178. public function isEnabled($cid){
  179. if(isset($this->database[$cid])){
  180. return $this->database[$cid][0];
  181. }
  182. return $this->config->get("default-enable");
  183. }
  184. public function setEnabled($cid, $bool){
  185. $this->database[$cid] = [$bool, $this->getLength($cid)];
  186. }
  187. public function getTesterMessage(){
  188. $numbers = "";
  189. for($i = 1; $i < 10; $i++){
  190. $numbers .= "$i";
  191. }
  192. for($i = 11; $i < 100; $i += 3){
  193. $numbers .= "$i,";
  194. }
  195. return [$this->lang["calibrate.instruction.close.screen"],
  196. $this->lang["calibrate.instruction.next.message"],
  197. $numbers,
  198. $this->lang["calibrate.instruction.hyphens.separator"],
  199. $this->lang["calibrate.instruction.ask.number"],
  200. $this->lang["calibrate.instruction.require.type.chat"]];
  201. }
  202. public function getData($cid){
  203. return $this->database[$cid];
  204. }
  205. public function processMessage($clientID, $message, Player $p){
  206. if(!$this->isEnabled($clientID)){
  207. return false;
  208. }
  209. $wrapped = explode("\n", wordwrap($message, $this->getLength($clientID), "\n"));
  210. if(count($wrapped) === 1){
  211. return false;
  212. }
  213. $packets = [];
  214. foreach($wrapped as $wrap){
  215. $pk = new MessagePacket;
  216. $pk->source = "clb.followup.linebreak";
  217. $pk->message = $wrap;
  218. $packets[] = $pk;
  219. }
  220. return $packets;
  221. }
  222. public function save(){
  223. $this->getLogger()->debug("Saving CLB database...");
  224. $time = microtime(true);
  225. $buffer = self::MAGIC_PREFIX;
  226. $buffer .= self::CURRENT_VERSION;
  227. foreach($this->database as $cid => $data){
  228. $buffer .= Binary::writeLong($cid);
  229. $ascii = $data[1];
  230. if($data[0]){
  231. $ascii |= 0b10000000;
  232. }
  233. $buffer .= chr($ascii);
  234. }
  235. $buffer .= self::MAGIC_SUFFIX;
  236. file_put_contents($this->path, $buffer, LOCK_EX);
  237. $this->getLogger()->debug("Done!", true, true, 2);
  238. }
  239. public function load(){
  240. $this->getLogger()->debug("Loading CLB database...");
  241. $time = 0 - microtime(true);
  242. $str = @file_get_contents($this->path);
  243. if($str === false){
  244. $this->save();
  245. return true;
  246. }
  247. $isOld = (strlen($str) % 9) === 0;
  248. if(!$isOld){
  249. if(substr($str, 0, strlen(self::MAGIC_PREFIX)) !== self::MAGIC_PREFIX){
  250. // TODO handle missing prefix database corruption
  251. $this->database = [];
  252. $this->save();
  253. trigger_error("CLB database corrupted. Component corrupted: " . self::CORRUPTION_PREFIX, E_USER_WARNING);
  254. }
  255. if(substr($str, -1 * strlen(self::MAGIC_SUFFIX)) !== self::MAGIC_SUFFIX){
  256. // TODO handle missing suffix database corruption
  257. $this->database = [];
  258. $this->save();
  259. trigger_error("CLB database corrupted. Component corrupted: " . self::CORRUPTION_SUFFIX, E_USER_WARNING);
  260. }
  261. $str = substr($str, strlen(self::MAGIC_PREFIX), -1 * strlen(self::MAGIC_SUFFIX));
  262. $api = substr($str, 0, 1);
  263. if($api > self::CURRENT_VERSION){
  264. // TODO handle incorrect API database corruption
  265. $this->database = [];
  266. $this->save();
  267. trigger_error("CLB database corrupted. Component corrupted: " . self::CORRUPTION_API, E_USER_WARNING);
  268. }
  269. $str = substr($str, 1);
  270. }
  271. for($i = 0; $i < strlen($str); $i += 9){
  272. $cur = substr($str, $i, 9);
  273. $key = Binary::readLong(substr($cur, 0, 8));
  274. $number = ord(substr($str, 8));
  275. $bool = ($number & 0b10000000) !== 0;
  276. $length = $number & 0b01111111;
  277. $this->database[$key] = [$bool, $length];
  278. }
  279. $time += microtime(true);
  280. $time *= 1000;
  281. $this->getLogger()->debug("Done! ($time ms)", true, true, 2);
  282. return false;
  283. }
  284. public function onDisable(){
  285. $this->save();
  286. }
  287. }