Advertisement
nick191821971782

Untitled

Jan 19th, 2020
233
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 42.04 KB | None | 0 0
  1. /*jshint esversion: 6 */
  2. /* jshint proto: true */
  3. // TODO: MOTM
  4. // TODO: ELO
  5. // TODO: kickonref
  6.  
  7. var room = HBInit({ roomName: "Bods Pub ||24/7|| Friends Only",
  8. playerName: "🌍", maxPlayers: 20, public: false });
  9. room.setDefaultStadium("Classic");
  10. room.setScoreLimit(3);
  11. room.setTimeLimit(3);
  12.  
  13.  
  14.  
  15. class Player {
  16. constructor(name) {
  17. this.name = name;
  18. /*************************************
  19. ************ Individual stats**********
  20. **************************************/
  21. this.goals = 0; /* Number of goals */
  22. this.assists = 0; /* Number of assists */
  23. this.cs = 0; /* Number of cleensheets */
  24. this.ownGoals = 0; /* Number of own goals */
  25. this.wins = 0; /* Number of wins */
  26. this.loses = 0; /* Number of loses */
  27. this.motm = 0; /* Number of time a player is the man of the match */
  28. this.playedGk = 0;
  29.  
  30. this.badPasses = 0; /* Number of passes */
  31. this.goodPasses = 1; /* Number of passes that reached a team mate */
  32. this.passAcc = 0; /* Pass accuracy % */
  33. this.motmRatio = 0; /* Man of the match % */
  34. this.winsRatio = 0; /* Wins / Loses */
  35. this.csPG = 0; /* CS % per game */
  36. this.goalsPG = 0; /* Number of goals per game */
  37. this.assistsPG = 0; /* Number of assists per game */
  38. this.elo = 1000; /* ELO */
  39.  
  40. this.secsPlayed = 0; /* Number of mins played */
  41. this.minsPlayed = 0; /* Number of mins played */
  42. this.currentStreak = 0; /* Number of current matches won in a row */
  43. this.bestStreak = 0; /* Number of maximum amount of wins in a row */
  44. this.statsString1 = "";
  45. this.statsString2 = "";
  46. this.statsString3 = "";
  47. /*************************************
  48. ************ Haxball manager**********
  49. **************************************/
  50. this.price = 10;
  51. this.money = 0;
  52. this.dreamTeam = {"gk": null, "dm": null, "am": null, "st": null};
  53. this.teamScore = 0;
  54.  
  55. /*************************************
  56. ************ Revelant to the room*****
  57. **************************************/
  58. this.team = 0;
  59. this.gotKicked = 0; /* Number of time this player got kicked by another player */
  60. this.kickedSomeone = 0; /* Number of time this player kicked someone */
  61. this.id = 0; /* Current player's id on the room */
  62. this.pw = 0; /* Password for player's account */
  63. this.isTrustedAdmin = 0; /* Whether he's a trusted admin */
  64. this.logged = 1; /* 0 if the player is not in the room, 1 if he's, 2 if he's logged */
  65. this.isBanned = 0; /* Whether a player is banned */
  66. this.isPermaBanned = 0; /* Whether a player is banned permanently*/
  67. this.isRegistered = 0; /* Whether a player is registered (e.g. his stats will count) */
  68. this.auth = 0; /* Player's last auth */
  69. this.isMuted = 0; /* Whether a player is muted */
  70. this.isAFK = false;
  71. }
  72.  
  73.  
  74. updateGoals(){
  75. if (gameStats.scorers.hasOwnProperty(this.name))
  76. this.goals += gameStats.scorers[this.name];
  77. }
  78. updateAssists(){
  79. if (gameStats.assisters.hasOwnProperty(this.name))
  80. this.assists += gameStats.assisters[this.name];
  81. }
  82. updateCs(){
  83. let [team, idteam] = this.team === 1 ? ["blueScore", 1] : ["redScore", 2];
  84. this.cs += gameStats[team] === 0 &&
  85. this.name === gameStats.Gks[idteam - 1];
  86. }
  87. updateOG(){
  88. if (gameStats.ownScorers.hasOwnProperty(this.name))
  89. this.ownGoals += gameStats.ownScorers[this.name];
  90. }
  91. updatePlayedGk(){
  92. this.playedGk += gameStats.Gks.includes(this.name);
  93. }
  94. updateWins(winningTeam){
  95. this.wins += this.team === winningTeam;
  96. }
  97.  
  98. updateLoses(losingTeam){
  99. this.loses += this.team === losingTeam;
  100. }
  101. updateWinRatio(){
  102. this.winsRatio = ((this.wins / (this.wins + this.loses)) * 100).toFixed(2) || 0;
  103. }
  104. updateGoalsPG(){
  105. this.goalsPG = (this.goals / (this.loses + this.wins)).toFixed(2) || 0;
  106. }
  107. updateAssistsPG(){
  108. this.assistsPG = (this.assists / (this.loses + this.wins)).toFixed(2) || 0;
  109. }
  110. updateCSPG(){
  111. this.csPG = ((this.cs / this.playedGk) * 100).toFixed(2) || 0;
  112. }
  113. updateCurrentStreak(won){
  114. this.currentStreak = won === this.team ? this.currentStreak + 1 : 0;
  115. }
  116.  
  117. updateBestStreak(){
  118. this.bestStreak = this.currentStreak >= this.bestStreak ?
  119. this.currentStreak : this.bestStreak;
  120. }
  121. updateSecsPlayed(){
  122. this.secsPlayed += ((this.team !== 0) / 60);
  123. }
  124. updateMinsPlayed(){
  125. this.minsPlayed = Math.floor((this.secsPlayed / 60));
  126. }
  127.  
  128. updatePassAccuracy(){
  129. this.passAcc = ((this.goodPasses / (this.goodPasses + this.badPasses)) * 100).toFixed(2);
  130. }
  131. updateKickedSomeone(){
  132. this.kickedSomeone += this.isTrustedAdmin === 0;
  133. }
  134. updatePassword(m){
  135. this.pw = m;
  136. }
  137. disconnect(){
  138. this.logged = 0;
  139. }
  140.  
  141. statsToString(){
  142. this.statsString1 = " | Goals: " + this.goals + " | Assists: " + this.assists +
  143. " | Own goals: " + this.ownGoals + " | cs: " + this.cs +
  144. " | Wins: " + this.wins + " | Losses: " + this.loses;
  145.  
  146. this.statsString2 = " | MOTM: " + "[Soon]" +
  147. " | MOTMR: " + "[Soon]" + " | W/L %: " + this.winsRatio +
  148. " | Pass acc %: " + this.passAcc + " | Elo: " + this.elo;
  149.  
  150. this.statsString3 = " | GPG: " + this.goalsPG + " | APG: " + this.assistsPG +
  151. " | csPG %: " + this.csPG +
  152. " | Best streak: " + this.bestStreak + " | Mins: " + this.minsPlayed;
  153. }
  154. displayStats(query_id){
  155. this.statsToString();
  156. room.sendChat(this.statsString1, query_id);
  157. room.sendChat(this.statsString2, query_id);
  158. room.sendChat(this.statsString3, query_id);
  159. }
  160. updateEGStats(){
  161. let winners = gameStats.redScore > gameStats.blueScore ? 1 : 2;
  162. let losers = 1 + (winners === 1);
  163. this.updateGoals();
  164. this.updateAssists();
  165. this.updateOG();
  166. this.updateWins(winners);
  167. this.updateLoses(winners - 1);
  168. this.updatePlayedGk();
  169.  
  170.  
  171. this.updateWinRatio();
  172. this.updateGoalsPG();
  173. this.updateAssistsPG();
  174. this.updateCSPG();
  175. this.updatePassAccuracy();
  176. this.updateCurrentStreak(winners);
  177. this.updateBestStreak(winners);
  178. this.updateCs();
  179. }
  180. }
  181.  
  182.  
  183.  
  184.  
  185. class GameStats {
  186. constructor() {
  187. this.redScore = 0; /* Number of goals red team scored this match */
  188. this.blueScore = 0; /* Number of goals blue team scored this match */
  189. this.Gks = ["", ""]; /* Name of the gks */
  190. this.scorers = {}; /* {name: number_of_goals_scored} */
  191. this.assisters = {}; /* {name: number_of_assists} */
  192. this.ownScorers = {}; /* {name: number_of_own_goals} */
  193. this.redTeam = []; /* [name of the players in red team] */
  194. this.blueTeam = []; /* [name of the players in blue team] */
  195. this.matchsumup = [];
  196. this.isOvertime = false;
  197. this.hasStarted = false;
  198. }
  199. updateScore(team){
  200. this.redScore += team === 1;
  201. this.blueScore += team === 2;
  202. }
  203.  
  204. updateGK(){
  205. var players = room.getPlayerList();
  206. var min = players[0];
  207. min.position = {x: room.getBallPosition().x + 60};
  208. var max = min;
  209.  
  210. for (var i = 1; i < players.length; i++) {
  211. if (players[i].position !== null){
  212. if (min.position.x > players[i].position.x) min = players[i];
  213. if (max.position.x < players[i].position.x) max = players[i];
  214. }
  215. }
  216. this.Gks = [min.name, max.name];
  217. }
  218. updateScorers(p, team){
  219. if (p.team === team) updateObject(this.scorers, p);
  220. }
  221. updateAssisters(p, team){
  222. if (p !== undefined && p.team === team) updateObject(this.assisters, p);
  223. }
  224. updateOwnScorers(p, team){
  225. if (p.team !== team) updateObject(this.ownScorers, p);
  226. }
  227.  
  228. updateRedTeam(){
  229. this.redTeam = room.getPlayerList().filter(player => player.team === 1);
  230. }
  231. updateBlueTeam(){
  232. this.blueTeam = room.getPlayerList().filter(player => player.team === 2);
  233. }
  234. updateOvertime(){
  235. this.isOvertime = true;
  236. }
  237. sumMatch(p){
  238. if (lastMatchSumUp.length === 0) return;
  239. let last_match = lastMatchSumUp.length - 1;
  240. let last_match_length = lastMatchSumUp[last_match].length;
  241. for (var i = 0; i < last_match_length; i++){
  242. room.sendChat(lastMatchSumUp[last_match][i], p.id);
  243. }
  244. }
  245.  
  246. }
  247.  
  248.  
  249.  
  250. class GameControl {
  251. constructor(radiusBall) {
  252. this.radiusBall = radiusBall || 10;
  253. this.triggerDistance = this.radiusBall + 15 + 0.1;
  254. this.currentBallOwner = "";
  255. this.lastBallOwners = ["", ""]; /* [name: name] */
  256. this.passesInARow = {"red": 0, "blue": 0}; /* {team: max} */
  257. this.maxPassesInARow = 0;
  258. this.redPoss = 0;
  259. this.bluePoss = 0;
  260. this.smth = "";
  261. }
  262. resetBallOwner(){
  263. this.currentBallOwner = "";
  264. this.lastBallOwners = ["", ""];
  265. }
  266. updateBallOwner(){
  267. var ballPosition = room.getBallPosition();
  268. var players = room.getPlayerList();
  269. var distanceToBall;
  270. for (var i = 0; i < players.length; i++) {
  271. if (players[i].position != null) {
  272. distanceToBall = pointDistance(players[i].position, ballPosition);
  273. if (distanceToBall < this.triggerDistance) {
  274. this.currentBallOwner = players[i].name;
  275. }
  276. }
  277. }
  278. }
  279. updateLastBallOwners(){
  280. if (this.currentBallOwner !== "" &&
  281. this.currentBallOwner !== this.lastBallOwners[0]){
  282.  
  283. this.lastBallOwners[1] = this.lastBallOwners[0];
  284. this.lastBallOwners[0] = this.currentBallOwner; // last player who touched the ball
  285. }
  286. }
  287. updatePassesInARow(){
  288. if (gameStats.redTeam.length !== gameStats.blueTeam.length ||
  289. gameStats.redTeam.length < 2) return;
  290.  
  291. if (this.lastBallOwners[1] !== "" && this.smth !== this.currentBallOwner){
  292.  
  293. if (Stats[this.lastBallOwners[0]].team ===
  294. Stats[this.lastBallOwners[1]].team){
  295.  
  296. Stats[this.lastBallOwners[1]].goodPasses +=
  297. Stats[this.lastBallOwners[1]].logged === 2;
  298.  
  299.  
  300. if (Stats[this.lastBallOwners[0]].team === 1){
  301. this.passesInARow.red += 1;
  302. this.updateMaxPassesInARow("blue");
  303. this.passesInARow.blue = 0;
  304. }
  305. else {
  306. this.passesInARow.blue += 1;
  307. this.updateMaxPassesInARow("red");
  308. this.passesInARow.red = 0;
  309.  
  310. }
  311. }
  312. else {
  313. Stats[this.lastBallOwners[1]].badPasses +=
  314. Stats[this.lastBallOwners[1]].logged === 2;
  315. }
  316.  
  317. this.smth = this.currentBallOwner;
  318. }
  319. }
  320. updateMaxPassesInARow(team){
  321. this.maxPassesInARow = this.passesInARow[team] > this.maxPassesInARow ?
  322. this.passesInARow[team] : this.maxPassesInARow;
  323. }
  324. }
  325.  
  326.  
  327. class Records {
  328. constructor() {
  329. this.bestPassesInARow = 0;
  330. this.bestAccuracy = "";
  331. this.bestStreak = {}; /*{[team]: score};*/
  332. this.fastestWin = 0;
  333. this.longestMatch = 0;
  334. }
  335. updateBestPassesInARow(){
  336. this.bestPassesInARow = this.maxPassesInARow > this.bestPassesInARow ?
  337. this.passesInARow : this.bestPassesInARow;
  338.  
  339. }
  340. }
  341.  
  342. class ELO {
  343. constructor() {
  344. this.redAverage = 0;
  345. this.blueAverage = 0;
  346. this.redChanceToWin = 0;
  347. this.blueChanceToWin = 0;
  348. this.redRating = 0;
  349. this.blueRating = 0;
  350. }
  351. getAverageRank(team){
  352. let average = 0;
  353. for (var i = 0; i < team.length; i++) {
  354. average += Stats[team[i].name].elo;
  355. }
  356. return average / team.length;
  357. }
  358. updateTeamAverages(){
  359. this.redAverage = this.getAverageRank(gameStats.redTeam);
  360. this.blueAverage = this.getAverageRank(gameStats.blueTeam);
  361. }
  362. updateChancesToWin(){
  363. this.redChanceToWin = 1 / ( 1 + Math.pow(10, (this.blueAverage - this.redAverage) / 400));
  364. this.blueChanceToWin = 1 / ( 1 + Math.pow(10, (this.redAverage - this.blueAverage) / 400));
  365. }
  366. updateRating(rwin, bwin){
  367. this.redRating = Math.round(32 * (rwin - this.redChanceToWin));
  368. this.blueRating = Math.round(32 * (bwin - this.blueChanceToWin));
  369. }
  370. handleEloCalc(){
  371. this.updateTeamAverages();
  372. this.updateChancesToWin();
  373. }
  374. updateElo(){
  375. if (gameStats.redTeam.length === gameStats.blueTeam.length){
  376. let winners = gameStats.redScore > gameStats.blueScore;
  377. let pr, pb;
  378. this.updateRating(winners, !winners);
  379. for (var i = 0; i < gameStats.redTeam.length; i++) {
  380. pr = gameStats.redTeam[i].name;
  381. pb = gameStats.blueTeam[i].name;
  382.  
  383. Stats[pr].elo += (Stats[pr].logged === 2) * this.redRating;
  384. Stats[pb].elo += (Stats[pb].logged === 2) * this.blueRating;
  385. }
  386. }
  387. }
  388. }
  389.  
  390. /**************************************************************
  391. * ************************** ADMINS ************************
  392. ***************************************************************/
  393.  
  394. var headAdminsAuths = {
  395. "fkHpAycYsCTx7RWCgSR42kUVoGA1IJo7t-mek2IHKkk": "Bods"
  396. };
  397.  
  398. var roomAdminsAuth = {};
  399.  
  400. function updateAdmins() {
  401. var players = room.getPlayerList().filter((player) => player.id != 0);
  402. if ( players.length == 0 ) return;
  403. if ( players.find((player) => player.admin) != null) return;
  404. room.setPlayerAdmin(players[0].id, true);
  405. }
  406.  
  407.  
  408. function superAdmin(p, m){
  409. if (headAdminsAuths.hasOwnProperty(Stats[p.name].auth)){
  410. var players = room.getPlayerList().filter((p) => p.admin === true);
  411. for (var i = 1; i < players.length; i++) {
  412. room.setPlayerAdmin(players[i].id,
  413. Stats[players[i].name].isTrustedAdmin >= 3 &&
  414. Stats[players[i].name].logged === 2);
  415. }
  416. room.setPlayerAdmin(p.id, true);
  417. Stats[p.name].isTrustedAdmin = 3;
  418. room.sendChat("You got super admin ! ", p.id);
  419. }
  420. return false;
  421. }
  422.  
  423. function getAdmin(p, m){
  424. if(m.substr("!admin".length + 1) === "imb0ds2"){
  425. room.setPlayerAdmin(p.id, true);
  426. }
  427. return false;
  428. }
  429.  
  430. function addAdmin(p, m){
  431. if (Stats[p.name].isTrustedAdmin >= 3){
  432. m = m.substr("!addadmin".length + 1);
  433. roomAdminsAuth[Stats[m].auth] = m;
  434. }
  435. }
  436.  
  437.  
  438. /**************************************************************
  439. * ************************** ANTI SPAM ************************
  440. * Function to call: handleSpam in room.onPlayerChat with
  441. * lastWriters and player as argument.
  442. * Purpose: This will kick a player after he talks 5 times
  443. * in a row.
  444. * Based on: player's id.
  445. * To change the number of chats allowed in a row, change the
  446. * const MAX_CHAT_IN_A_ROW to what you want.
  447. * Global variables used:
  448. * lastWriters (array of int)
  449. * const int MAX_CHAT_IN_A_ROW
  450. * const string KICK_MESSAGE_SPAM
  451. ***************************************************************/
  452. var lastWriters = [];
  453. const MAX_CHAT_IN_A_ROW = 25;
  454. const KICK_MESSAGE_SPAM = "Stop spamming! Thanks.";
  455.  
  456. /**************************************************************
  457. * Function returning how much time the last player who wrote
  458. * in chat has previously written.
  459. ***************************************************************/
  460.  
  461. function checkSpam(lastWriters, p){
  462. let c = 0;
  463. for (var i = 0; i < lastWriters.length; i++){
  464. c += lastWriters[i] === p.id;
  465. }
  466. return c;
  467. }
  468.  
  469. /**************************************************************
  470. * Function updating the array by deleting the first element
  471. * and adding the last player who talked.
  472. ***************************************************************/
  473. function updateLastWriters(lastWriters, p){
  474. lastWriters.splice(0, 1);
  475. lastWriters.push(p.id);
  476.  
  477. }
  478.  
  479. /**************************************************************
  480. * Function updating the array and kicking a spammer with the
  481. * message KICK_MESSAGE_SPAM.
  482. * When the array's length is smaller than MAX_CHAT_IN_A_ROW
  483. * (so at the beginning of a room) it doesnt check spam
  484. * but simply fills it.
  485. ***************************************************************/
  486.  
  487.  
  488. function handleSpam(lastWriters, p){
  489. if (lastWriters.length === MAX_CHAT_IN_A_ROW){
  490. updateLastWriters(lastWriters, p);
  491. let res = checkSpam(lastWriters, p);
  492.  
  493. if (res === MAX_CHAT_IN_A_ROW){
  494. room.kickPlayer(p.id, KICK_MESSAGE_SPAM, 0);
  495. }
  496. }
  497. else {
  498. lastWriters.push(p.id);
  499. }
  500. }
  501.  
  502.  
  503. /**************************************************************
  504. * ************************** SWAP *****************************
  505. * Function to call: swap
  506. * If it's used as a command, the parameter has to be an admin player.
  507. * Otherwise this function can just be called with no param to work.
  508. * This function put the red (resp blue) team into blue (resp red).
  509. * Global variable used: None.
  510. ***************************************************************/
  511.  
  512.  
  513. function swap(player){
  514. if (player === undefined || player.admin !== 0){
  515. var p = room.getPlayerList().filter((player) => player.id != 0);
  516. for (let i = 0; i < p.length; i++){
  517. if (p[i].team !== 0){
  518. room.setPlayerTeam(p[i].id, 1 + (p[i].team === 1));
  519. }
  520. }
  521. }
  522. return false;
  523. }
  524.  
  525.  
  526. /**************************************************************
  527. * ************************** PM *******************************
  528. * Function to call: sendPM.
  529. * Use: @player [message]
  530. * This function will send a private message to the player.
  531. * Global variable used: None.
  532. ***************************************************************/
  533.  
  534. function sendPM(p, m){
  535. if (m.startsWith("@") === true){
  536. let spacePos = m.search(" ");
  537. let name = m.substr(1, spacePos !== -1 ? spacePos - 1: m.length);
  538. let dest = room.getPlayerList().filter((p) => p.name === name);
  539. if (dest.length !== 0){
  540. m = m.substr(spacePos, m.length);
  541. room.sendChat("PM from " + p.name + ": " + m, dest[0].id);
  542. }
  543. return false;
  544. }
  545. return true;
  546. }
  547.  
  548. /**************************************************************
  549. * ************************** Resets ****************************
  550. * Functions to call: reset and resetWithSwap.
  551. * If it's used as a command, the parameter has to be an admin player.
  552. * Otherwise this function can just be called with no param to work.
  553. * These functions allow to reset the game by typing !rr
  554. * And to reset the game by switching teams by typing !rrs
  555. * Global variables used: None
  556. ***************************************************************/
  557.  
  558. function reset(p){
  559. if (p === undefined || p.admin === true){
  560. room.stopGame();
  561. room.startGame();
  562. }
  563. }
  564.  
  565. function resetWithSwap(p){
  566. if (p === undefined || p.admin === true){
  567. room.stopGame();
  568. swap();
  569. room.startGame();
  570. }
  571. }
  572. function resetWithTop(p){
  573. if (p === undefined || p.admin === true){
  574. room.stopGame();
  575. let specs = room.getPlayerList().filter((p) => p.id !== 0 && p.team === 0);
  576. if (specs.length !== 0){
  577. room.setPlayerTeam(specs[0], p.team === 1 ? 2 : 1);
  578. }
  579. room.startGame();
  580. }
  581. }
  582.  
  583. /**************************************************************
  584. * ************************** ACCOUNT **************************
  585. * Function to call: almost all of theses are commands.
  586. * These functions will simulate a way to have an account in the room.
  587. * To further details, read the documentation of each function.
  588. * There can be only one account per nickname.
  589. * Global variables used: Stats {name: p | p € class Player }
  590. ***************************************************************/
  591. var Stats = {};
  592. function loadStats(){
  593. if (localStorage.getItem("Players_Stats")){
  594. let all = JSON.parse(localStorage.getItem("Players_Stats"));
  595. let noms = Object.keys(all);
  596. for (let i = 0; i < noms.length; i++){
  597. Stats[noms[i]] = new Player(noms[i]);
  598. Object.assign(Stats[noms[i]], all[noms[i]]);
  599. }
  600. }
  601.  
  602. }
  603.  
  604.  
  605. function saveStatsFun(){
  606. var val = JSON.stringify(Stats);
  607. window.localStorage.setItem("Players_Stats", val);
  608. }
  609.  
  610.  
  611.  
  612. /**************************************************************
  613. * Function creating a new account for the player if this nick
  614. * never been to the room.
  615. * Also logs him and get his current id.
  616. ***************************************************************/
  617. function autoConnect(p){
  618. if (Stats.hasOwnProperty(p.name) === false){
  619. Stats[p.name] = new Player(p.name);
  620. }
  621. Stats[p.name].logged = 1;
  622. Stats[p.name].id = p.id;
  623. Stats[p.name].auth = p.auth;
  624. }
  625.  
  626. /**************************************************************
  627. * Function used as a command : !register [password].
  628. * Having an account doesn't mean that a player is registered,
  629. * Being registered allows the player to log in in order to
  630. * be able to have his own stats and other privileges.
  631. * This command register a player with his chosen password if
  632. * he never been
  633. ***************************************************************/
  634. function register(p, m){
  635. if (Stats[p.name].isRegistered === 0){
  636. m = m.substr("!register".length + 1);
  637. room.sendChat("PM from Host: You are now registered with the password " + m, p.id);
  638. Stats[p.name].pw = m;
  639. Stats[p.name].isRegistered = 1;
  640. }
  641. else {
  642. room.sendChat("PM from Host: You are already registered, please use !login [pw].", p.id);
  643. }
  644. return false;
  645. }
  646. /**************************************************************
  647. * Function used as a command : !login [password].
  648. * This command logs the player in order to activate his privileges
  649. * Stats only count where player.logged is equal to 2.
  650. ***************************************************************/
  651. function login(p, m){
  652. if (p.team !== 0 && room.getScores() !== null){
  653. room.sendChat("PM from Host: You can't log in during a game :(");
  654. return false;
  655. }
  656. if (Stats[p.name].isRegistered === 1 ){
  657. m = m.substr("!login".length + 1);
  658. if (Stats[p.name].pw === m && Stats[p.name].logged !== 2){
  659. room.sendChat("PM from Host: You successfully connected !", p.id);
  660. Stats[p.name].logged = 2;
  661. }
  662. else {
  663. room.sendChat("PM from Host: Wrong password. Ask us on discord if there's a problem!", p.id);
  664. }
  665. }
  666. else {
  667. room.sendChat("PM from Host: You are not registered, please use !register [pw].", p.id);
  668. }
  669. return false;
  670. }
  671.  
  672. /**************************************************************
  673. * Function used as a command : !logout
  674. * Reciprocal function to login, this put the player.logged to 1
  675. * meaning his stats won't count anymore.
  676. ***************************************************************/
  677. function logout(p){
  678. if (p.team !== 0 && room.getScores() !== null){
  679. room.sendChat("PM from Host: You can't log out during a game :(");
  680. return false;
  681. }
  682. if (Stats[p.name].logged === 2){
  683. Stats[p.name].logged = 1;
  684. room.sendChat("PM from Host: You logged out.", p.id);
  685. }
  686. else {
  687. room.sendChat("PM from Host: You weren't in.", p.id);
  688. }
  689. return false;
  690. }
  691.  
  692.  
  693. function stats(p, m){
  694. m = m.substr("!stats".length + 1);
  695. if (Stats.hasOwnProperty(m)){
  696. Stats[m].displayStats(p.id);
  697. }
  698. else {
  699. room.sendChat("This player is not in our database.", p.id);
  700. }
  701. return false;
  702. }
  703.  
  704.  
  705. var msg_to_command = {
  706. "goals": "goals",
  707. "assists": "assists",
  708. "og": "ownGoals",
  709. "cs": "cs",
  710. "wins": "wins",
  711. "losses": "loses",
  712. "wl": "winsRatio",
  713. "passacc": "passAcc",
  714. "elo": "elo",
  715. "gpg": "goalsPG",
  716. "apg": "assistsPG",
  717. "cspg": "csPG",
  718. "streak": "bestStreak",
  719. "mins": "minsPlayed",
  720. };
  721.  
  722.  
  723.  
  724.  
  725. function bestRanks(message){
  726. if (!msg_to_command.hasOwnProperty(message))
  727. return "This option does not exist (yet ?), sorry :(. See !rankhelp to further infos.";
  728.  
  729. let cmd = msg_to_command[message];
  730. let names = Object.keys(Stats);
  731. let score;
  732. let string = "";
  733. let overall = [];
  734. for (var i = 0; i < names.length; i++) {
  735. if (!Stats.hasOwnProperty(names[i])) continue;
  736. score = Stats[names[i]][cmd];
  737. if (score === 1000 || score === 0) continue;
  738.  
  739. overall.push({name: names[i], value: score});
  740. }
  741. overall.sort(function(a,b){
  742. return b.value - a.value;
  743. });
  744. for (i = 0; i < overall.length; i++) {
  745. string += i + 1 + ") " + overall[i].name + ": " + overall[i].value + " | ";
  746. }
  747. return string;
  748. }
  749.  
  750.  
  751.  
  752. function ranking(p, m){
  753. let string = bestRanks(m.substr("!rank".length + 1));
  754. let line1 = string.substring(0, 80);
  755. let line2 = string.substring(80, 160);
  756. let line3 = string.substring(160, 240);
  757. room.sendChat(line1, p.id);
  758. room.sendChat(line2, p.id);
  759. room.sendChat(line3, p.id);
  760. return false;
  761. }
  762.  
  763. /**************************************************************
  764. * Function as a command: !bb
  765. * Kicks the player from the room with disconnecting him
  766. * (the disconnect thing is pretty useless since it is caught
  767. * in the onPlayerLeave anyway).
  768. ***************************************************************/
  769. function bb(p){
  770. Stats[p.name].disconnect();
  771. room.kickPlayer(p.id, "rip !", false);
  772. }
  773.  
  774.  
  775. /**************************************************************
  776. * ************************** MUTE ****************************
  777. * Global variable used: None
  778. ***************************************************************/
  779. function mute(p, m){
  780. if (p === undefined && Stats[player.name].isTrustedAdmin >= 1 &&
  781. Stats[player.name].logged === 2){
  782. m = m.substr("!mute".length + 1);
  783. if (Stats.hasOwnProperty(m)) {
  784. Stats[m].isMuted = 1;
  785. room.sendChat(m + " has been muted by " + p.name);
  786. }
  787. }
  788. return false;
  789. }
  790.  
  791. function muteById(p, m){
  792. m = idToName(m.substr("!muteid".length + 1));
  793. return mute(p, "!mute " + m);
  794. }
  795.  
  796.  
  797. function unmute(p, m){
  798. if (p === undefined && Stats[player.name].isTrustedAdmin >= 1 &&
  799. Stats[player.name].logged === 2){
  800. m = m.substr("!unmute".length + 1);
  801. if (Stats.hasOwnProperty(m)) {
  802. Stats[m].isMuted = 0;
  803. room.sendChat(m + " has been unmuted by " + p.name);
  804. room.sendChat(m + " has been unmuted by " + Stats[m].id);
  805. }
  806. }
  807. return false;
  808. }
  809.  
  810. function unmuteById(p, m){
  811. m = idToName(m.substr("!unmuteid".length + 1));
  812. return unmute(p, "!unmute " + m);
  813. }
  814.  
  815. function muteAll(p, m){
  816. if (p === undefined || p.admin === true){
  817. var players = room.getPlayerList().filter((p) => p.admin === false &&
  818. p.team === 0);
  819. for (var i = 0; i < players.length; i++) {
  820. Stats[players[i]].isMuted = 1;
  821. }
  822. }
  823. }
  824.  
  825. function resetMutes(p){
  826. if (p === undefined || p.admin === true){
  827. var players = room.getPlayerList();
  828. for (var i = 1; i < players.length; i++) {
  829. Stats[players[i].name].isMuted = 0;
  830. }
  831. }
  832. return false;
  833. }
  834.  
  835. /**************************************************************
  836. * ************************** BANS ****************************
  837. * Function to call: almost all of theses are commands.
  838. * These functions are set in order to ban toxic people.
  839. * This includes simple bans, simple clearing bans but also
  840. * permaban that can be only disabled by the vps owner.
  841. * In order to make this last feature work, room.clearBans is
  842. * never used.
  843. * Global variables used: None.
  844. ***************************************************************/
  845.  
  846. function permaBan(p, m){
  847. if (p === undefined || Stats[p.name].isTrustedAdmin >= 3 &&
  848. Stats[p.name].logged === 2){
  849.  
  850. m = m.substr("!permaban".length + 1);
  851. if (Stats.hasOwnProperty(m) === true){
  852. room.sendChat(m + " has been banned permanently !");
  853. Stats[m].isBanned = true;
  854. Stats[m].isPermaBanned = 1;
  855. room.kickPlayer(Stats[m].id, "You have been permanently banned", 1);
  856. }
  857. }
  858. else {
  859. room.sendChat("PM from Host: Only trusted admin with the level 3 or higher are allowed to permaban.", p.id);
  860. }
  861. return false;
  862. }
  863.  
  864.  
  865. function idToName(m){
  866. if (!m.isNaN){
  867. let player = room.getPlayer(m);
  868. if (player !== null)
  869. return player.name;
  870. }
  871. return m;
  872. }
  873.  
  874. function permaBanById(p, m){
  875. m = idToName(m.substr("!permabanid".length + 1));
  876. return permaBan(p, "!permaban " + m);
  877. }
  878.  
  879.  
  880. function unbanAll(player){
  881. if (player === undefined && Stats[player.name].isTrustedAdmin >= 1 &&
  882. Stats[player.name].logged === 2){
  883. for (var p in Stats) {
  884. if (Stats.hasOwnProperty(p) && Stats[p].isBanned === true &&
  885. Stats[p].isPermaBanned === 0) {
  886.  
  887. room.clearBan(Stats[p].id);
  888. Stats[p].isBanned = 0;
  889. }
  890. }
  891. room.sendChat("PM from Host: Bans have been cleared.");
  892. }
  893. return false;
  894. }
  895.  
  896. function unbanPlayer(p, m){
  897. if (p === undefined && Stats[player.name].isTrustedAdmin >= 1 &&
  898. Stats[player.name].logged === 2){
  899. m = m.substr("!unban".length + 1);
  900. if (Stats.hasOwnProperty(m) === true){
  901. room.clearBan(Stats[m].id);
  902. room.sendChat(m + " is free now !", p.id);
  903. Stats[m].isBanned = 0;
  904. }
  905. }
  906. return false;
  907. }
  908.  
  909.  
  910.  
  911.  
  912.  
  913. /**************************************************************
  914. * ********************* MISC COMMANDS *************************
  915. * Miscellaneous functions related to some pretty commands.
  916. * Global variable used: None.
  917. ***************************************************************/
  918.  
  919. /**************************************************************
  920. * Function displaying help in 2 lines in pm to the player.
  921. ***************************************************************/
  922. function helpFun(p){
  923. var help_string1 = "| !register [password] | !login [password] | !stats [nickname] | !rank [arg] | !rankhelp ";
  924. var help_string2 = "| !logout | !bb | !swap | !rr | !rrs | !msup | @nickname pm | !discord | !afks | !admin [pw]";
  925. var help_string3 = "| !mute [nickname] | !muteid [id] | !unmuteid [id] | !permaban [nickname] | !permabanid [id] ";
  926. var help_string4 = "| !unban [nickname] | !muteall | !unmuteall | !unbanall | !map [name] ";
  927. room.sendChat(help_string1, p.id);
  928. room.sendChat(help_string2, p.id);
  929. room.sendChat(help_string3, p.id);
  930. room.sendChat(help_string4, p.id);
  931. return false;
  932. }
  933.  
  934.  
  935. function rankHelp(p){
  936. room.sendChat("Type rank + one options among: ", p.id);
  937. room.sendChat(Object.keys(msg_to_command).join(" | "), p.id);
  938. return false;
  939. }
  940. /**************************************************************
  941. * Function putting the player to afk state or getting him back.
  942. * The player is automatically switched in spec after typing this.
  943. ***************************************************************/
  944. function afk(p){
  945. let state = Stats[p.name].isAFK === false ? "afk !" : "back !";
  946. room.sendChat(p.name + " is " + state);
  947. if (state === "afk !") room.setPlayerTeam(p.id, 0);
  948. Stats[p.name].isAFK = !(Stats[p.name].isAFK);
  949. return false;
  950. }
  951.  
  952.  
  953. /**************************************************************
  954. * Function displaying the sum up of the last match in pm.
  955. ***************************************************************/
  956. function sumMatchCommand(p){
  957. gameStats.sumMatch(p);
  958. return false;
  959. }
  960.  
  961.  
  962. function givesDiscord(p){
  963. room.sendChat("Retirement Home 4v4/9v9: https://discord.gg/4c5YZqH || SHHA 3v3 Noob League: https://discord.gg/suaKRyW", p.id);
  964. }
  965.  
  966. function displayAfks(p){
  967. let players = room.getPlayerList().filter((player) => player.id != 0);
  968. let string = "PM from Host: ";
  969. for (var i = 0; i < players.length; i++) {
  970. if (Stats[players[i].name].isAFK)
  971. string += players[i].name + " | ";
  972. }
  973. room.sendChat(string, p.id);
  974. return false;
  975. }
  976.  
  977. function disconnectAll(){
  978. let p = Object.keys(Stats);
  979. for (var i = 0; i < p.length; i++) {
  980. Stats[p[i]].logged = 0;
  981. }
  982. }
  983.  
  984.  
  985.  
  986. /*
  987. function changeMaps(p, m){
  988. if (p === undefined || p.admin === true){
  989. m = m.substr("!map".length + 1);
  990. if (maps.hasOwnProperty(m)){
  991. room.setCustomStadium(maps[m]);
  992. return false;
  993. }
  994. room.sendChat("PM from Host: This map does not exist, maps: " +
  995. Object.keys(map).join(" | "));
  996. }
  997. }
  998. */
  999.  
  1000.  
  1001. var commands = {
  1002. "!swap": swap,
  1003. "!rr": reset,
  1004. "!rrs": resetWithSwap,
  1005. //"!rrt": resetWithTop,
  1006. "!bb": bb,
  1007. "!afk": afk,
  1008. "!msup": sumMatchCommand,
  1009. "!discord": givesDiscord,
  1010. "!help": helpFun,
  1011. "!rankhelp": rankHelp,
  1012. "!afks": displayAfks,
  1013. "!stats": stats,
  1014. "!rank": ranking,
  1015. "!register": register,
  1016. "!login": login,
  1017. "!logout": logout,
  1018.  
  1019. "!mute": mute,
  1020. "!muteid": muteById,
  1021. "!muteall": muteAll,
  1022. "!unmute": unmute,
  1023. "!unmuteid": unmuteById,
  1024. "!unmuteall": resetMutes,
  1025. "!unban": unbanPlayer,
  1026. "!unbanall": unbanAll,
  1027. "!permaban": permaBan,
  1028. "!permabanid": permaBanById,
  1029. "!superadmin": superAdmin,
  1030. "!admin": getAdmin,
  1031. "!addadmin": addAdmin,
  1032. //"!map": changeMaps,
  1033. };
  1034.  
  1035.  
  1036. function handleCommands(p, m){
  1037. let spacePos = m.search(" ");
  1038. let command = m.substr(0, spacePos !== -1 ? spacePos : m.length);
  1039. if (commands.hasOwnProperty(command) === true) return commands[command](p, m);
  1040. if (m.startsWith("!") === true) {
  1041. room.sendChat("PM from Host: This is not an existing command, write !help if needed !", p.id);
  1042. return false;
  1043. }
  1044. return true;
  1045. }
  1046.  
  1047.  
  1048. function handleStart(){
  1049. gameStats.updateRedTeam();
  1050. gameStats.updateBlueTeam();
  1051. handleTeams();
  1052. elo.handleEloCalc();
  1053. }
  1054.  
  1055.  
  1056. function handleTimePlayed(){
  1057. var players = room.getPlayerList();
  1058. for (var i = 1; i < players.length; i++){
  1059. Stats[players[i].name].updateSecsPlayed();
  1060. Stats[players[i].name].updateMinsPlayed();
  1061. }
  1062. }
  1063.  
  1064.  
  1065.  
  1066. function handleGoals(team){
  1067. var time = room.getScores().time;
  1068. var m = Math.trunc(time / 60);
  1069. var s = Math.trunc(time % 60);
  1070. let string;
  1071. let assister = "";
  1072.  
  1073. time = m + ":" + (s < 10 ? "0" + s : s); // MM:SS format
  1074. gameStats.updateScore(team);
  1075.  
  1076. gameStats.updateScorers(Stats[gameControl.currentBallOwner], team);
  1077. gameStats.updateOwnScorers(Stats[gameControl.currentBallOwner], team);
  1078. gameStats.updateAssisters(Stats[gameControl.lastBallOwners[1]], team);
  1079.  
  1080. if (Stats.hasOwnProperty(gameControl.lastBallOwners[1]) &&
  1081. (Stats[gameControl.lastBallOwners[1]].team ===
  1082. Stats[gameControl.lastBallOwners[0]].team)){
  1083.  
  1084. assister = gameControl.lastBallOwners[1];
  1085. }
  1086.  
  1087.  
  1088. if (team === Stats[gameControl.currentBallOwner].team){
  1089. string = "Scorer: " + gameControl.lastBallOwners[0] + "| Assister: " +
  1090. assister + "| at " + time;
  1091. room.sendChat(string);
  1092. }
  1093. else {
  1094. string = "Own goal from: " + gameControl.lastBallOwners[0] + "| at " + time;
  1095. room.sendChat(string);
  1096. }
  1097. gameStats.matchsumup.push(string);
  1098. gameControl.resetBallOwner();
  1099.  
  1100. }
  1101.  
  1102. function handleTeams(){
  1103. var p = room.getPlayerList();
  1104. for (var i = 1; i < p.length; i++) {
  1105. Stats[p[i].name].team = p[i].team;
  1106.  
  1107. }
  1108. }
  1109.  
  1110. function handleGk(){
  1111. if (gameStats.hasStarted === false){
  1112. if (room.getScores().time !== 0){
  1113. gameStats.hasStarted = true;
  1114. gameStats.updateGK();
  1115. room.sendChat("Red GK: " + gameStats.Gks[0] + ", Blue GK: " + gameStats.Gks[1]);
  1116. }
  1117. }
  1118. }
  1119.  
  1120. function handleEndGame(){
  1121. var players = room.getPlayerList().filter((p) => p.id != 0);
  1122. records.updateBestPassesInARow();
  1123. elo.updateElo();
  1124. for (var i = 0; i < players.length; i++){
  1125. if (Stats[players[i].name].logged === 2){
  1126. Stats[players[i].name].updateEGStats();
  1127. }
  1128. }
  1129. }
  1130.  
  1131. function handleOvertime(){
  1132. let scores = room.getScores();
  1133. if (scores !== null && scores.timeLimit !== 0 &&
  1134. scores.time >= scores.timeLimit){
  1135.  
  1136. handleEndGame();
  1137. }
  1138. }
  1139.  
  1140.  
  1141.  
  1142. function handleBans2(kicked, message, ban, by){
  1143. if (by.id !== 0){
  1144. if (Stats[by.name].isTrustedAdmin === 0 && ban){
  1145. room.kickPlayer(by.id, "You are not allowed to ban players !", 1);
  1146. room.clearBan(kicked.id);
  1147. }
  1148. }
  1149. }
  1150. function handleBans(kicked, message, ban, by){
  1151. Stats[kicked.name].gotKicked += by !== null;
  1152. Stats[kicked.name].isBanned = ban === true;
  1153. if (by.id !== 0){
  1154. Stats[by.name].updateKickedSomeone();
  1155. if (Stats[by.name].kickedSomeone >= 10){
  1156. Stats[by.name].kickedSomeone = 0;
  1157. room.kickPlayer(by.id, "You kicked too much people", 1);
  1158. }
  1159. }
  1160. }
  1161.  
  1162. function handleRefresh(p){
  1163. if (Stats.hasOwnProperty(p.name) && Stats[p.name].logged !== 0){
  1164. if (Stats[p.name].auth === p.auth){
  1165. room.kickPlayer(Stats[p.name].id, "You just refreshed.", 0);
  1166. }
  1167. else {
  1168. room.kickPlayer(p.id, "This nickname is already taken in the room.", 0);
  1169. }
  1170. }
  1171. }
  1172.  
  1173. function handleAFK(p){
  1174. if (Stats[p.name].isAFK === true){
  1175. room.setPlayerTeam(p.id, 0);
  1176. room.sendChat(p.name + " is afk, you can't move him.");
  1177. }
  1178. }
  1179.  
  1180. function handleCSMessage(){
  1181. let str = "";
  1182. if (gameStats.redScore === 0)
  1183. str = [gameStats.Gks[1] + " kept a cs for his team"].join();
  1184. if (gameStats.blueScore === 0)
  1185. str = [gameStats.Gks[0] + " kept a cs for his team"].join();
  1186. return str;
  1187. }
  1188.  
  1189.  
  1190. function handleMode(){
  1191. mode = room.getScores().timeLimit === 7;
  1192. }
  1193.  
  1194. var Alts = {}; //{conn: [name1, ..., nameN]}
  1195.  
  1196. function handleAlts(p){
  1197. if (Alts.hasOwnProperty(p.conn)){
  1198. if (!Alts[p.conn].includes(p.name))
  1199. Alts[p.conn].push(p.name);
  1200. }
  1201. else {
  1202. Alts[p.conn] = [p.name];
  1203. }
  1204. }
  1205.  
  1206. function handleBans(p){
  1207. if (Stats[p.name].isBanned != 0)
  1208. room.kickPlayer(p.id, "You're banned permanently", 1);
  1209. }
  1210. /*
  1211. function handleStadiumChange(name, by){
  1212. if (by !== undefined){
  1213. room.kickPlayer("Please use !map [stadium] next time !", false);
  1214. room.setCustomStadium(maps.big);
  1215. }
  1216. }
  1217. */
  1218. /**************************************************************
  1219. * ************************** EVENTS ****************************
  1220. ***************************************************************/
  1221. var gameStats = new GameStats();
  1222. var gameControl = new GameControl(5.9);
  1223. var records = new Records();
  1224. var elo;
  1225. var mode = false;
  1226. var lastMatchSumUp = [];
  1227. setInterval(saveStatsFun, 300000);
  1228.  
  1229. room.onPlayerChat = function(p, m){
  1230. if (Stats[p.name].isMuted) return false;
  1231. if (handleCommands(p, m) === false) return false;
  1232. if (sendPM(p, m) === false) return false;
  1233. handleSpam(lastWriters, p);
  1234. };
  1235.  
  1236.  
  1237. room.onPlayerTeamChange = function(p, by){
  1238. handleAFK(p);
  1239. handleTeams();
  1240. };
  1241.  
  1242.  
  1243.  
  1244.  
  1245. room.onPlayerJoin = function(player) {
  1246. handleRefresh(player);
  1247. autoConnect(player);
  1248. handleBans(player);
  1249. handleAlts(player);
  1250. updateAdmins();
  1251. room.sendChat("Hey " + player.name + " ! welcome to Bod's pub" +
  1252. " type !help if needed !", player.id);
  1253. };
  1254.  
  1255. room.onPlayerLeave = function(player) {
  1256. updateAdmins();
  1257. Stats[player.name].disconnect();
  1258. };
  1259.  
  1260.  
  1261.  
  1262.  
  1263. room.onPlayerKicked = function(kicked, message, ban, by){
  1264. handleBans2(kicked, message, ban, by);
  1265. };
  1266.  
  1267.  
  1268. room.onGameStart = function(){
  1269. gameStats = new GameStats();
  1270. gameControl = new GameControl(5.9);
  1271. elo = new ELO();
  1272. handleStart();
  1273. handleMode();
  1274.  
  1275. };
  1276.  
  1277.  
  1278. room.onTeamGoal = function(team){
  1279. handleGoals(team);
  1280. };
  1281.  
  1282.  
  1283. room.onGameStop = function(){
  1284. resetMutes();
  1285. gameControl.resetBallOwner();
  1286.  
  1287. };
  1288.  
  1289.  
  1290.  
  1291. room.onGameTick = function(){
  1292. gameControl.updateBallOwner();
  1293. gameControl.updateLastBallOwners();
  1294. gameControl.updatePassesInARow();
  1295. handleGk();
  1296. handleTimePlayed();
  1297. if (mode === true) setInterval(handleOvertime, 5000);
  1298. };
  1299.  
  1300. room.onPlayerBallKick = function (player){
  1301. gameControl.currentBallOwner = player.name;
  1302. };
  1303.  
  1304.  
  1305. room.onTeamVictory = function(){
  1306. if (mode === false) handleEndGame();
  1307. gameStats.matchsumup.push(handleCSMessage());
  1308. lastMatchSumUp.push(gameStats.matchsumup);
  1309.  
  1310. };
  1311.  
  1312. room.onRoomLink = function(){
  1313. disconnectAll();
  1314. autoConnect(room.getPlayer(0));
  1315. loadStats();
  1316. };
  1317.  
  1318. /*
  1319. room.onStadiumChange = function(name, by){
  1320. handleStadiumChange(name, by);
  1321. };
  1322. */
  1323. /* EOF */
  1324.  
  1325.  
  1326. /* Python-like update dict method having at least an empty object */
  1327. function updateObject(object, p){
  1328. if (object.hasOwnProperty(p.name)){
  1329. object[p.name]++;
  1330. }
  1331. else {
  1332. object[p.name] = 1;
  1333. }
  1334. }
  1335.  
  1336.  
  1337. // Gives the last player who touched the ball, works only if the ball has the same
  1338. // size than in classics maps.
  1339. // Calculate the distance between 2 points
  1340. function pointDistance(p1, p2) {
  1341. var d1 = p1.x - p2.x;
  1342. var d2 = p1.y - p2.y;
  1343. return Math.sqrt(d1 * d1 + d2 * d2);
  1344. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement