From a4d0d1190b74cd1bfb596b8a02a2deacce3ad86c Mon Sep 17 00:00:00 2001 From: Kyle Gunger Date: Fri, 28 Feb 2020 02:21:30 -0500 Subject: Fix mobile + Lobby omments --- client.html | 18 ++-- scripts/client.js | 105 +++++++++++++++++++++++ scripts/client/client.js | 105 ----------------------- scripts/client/lobby.js | 102 ---------------------- scripts/client/message.js | 14 ---- scripts/client/sock.js | 52 ------------ scripts/client/table.js | 16 ---- scripts/libs/discord-rpc.js | 8 -- scripts/lobby.js | 200 ++++++++++++++++++++++++++++++++++++++++++++ scripts/message.js | 14 ++++ scripts/sock.js | 52 ++++++++++++ scripts/table.js | 16 ++++ styles/client/mobile.css | 2 +- 13 files changed, 397 insertions(+), 307 deletions(-) create mode 100644 scripts/client.js delete mode 100644 scripts/client/client.js delete mode 100644 scripts/client/lobby.js delete mode 100644 scripts/client/message.js delete mode 100644 scripts/client/sock.js delete mode 100644 scripts/client/table.js delete mode 100644 scripts/libs/discord-rpc.js create mode 100644 scripts/lobby.js create mode 100644 scripts/message.js create mode 100644 scripts/sock.js create mode 100644 scripts/table.js diff --git a/client.html b/client.html index 5203ee3..b48e54c 100644 --- a/client.html +++ b/client.html @@ -2,7 +2,8 @@ - + + @@ -12,12 +13,11 @@ - - - - - - + + + + + @@ -28,8 +28,8 @@
- - + +
diff --git a/scripts/client.js b/scripts/client.js new file mode 100644 index 0000000..b5dd4bf --- /dev/null +++ b/scripts/client.js @@ -0,0 +1,105 @@ +// Client acts as the message hub for the whole game. +// WebSocket messages come into Client and Client redirects them to the lobby or table based on the state of the game. +// Client also performs the handshake for first starting the connection and messages everyone if the connection errors or closes. +function Client(serveraddr, game) { + this.state = "handshake"; + + this.soc = new SockWorker(serveraddr, "1", this.cb.bind(this)); + + this.lob = new Lobby(document.getElementsByClassName("lobby")[0], this.soc); + this.tab = new Table(document.getElementsByClassName("table")[0], this.soc); + + this.game = game; +} + +Client.prototype = { + init: function() { + this.soc.init(); + }, + + // Entry point for a message. + // If it's a close message, the + cb: function(m) { + console.log(m); + + if(m.type == "error" || m.type == "closed") { + var t = m.type; + t = t[0].toUpperCase() + t.slice(1) + this.lob.setState(t, "#D00", this.soc.server); + this.tab.handleClose(); + return; + } + + switch(this.state) { + case "handshake": + this.handshake(m); + break; + case "lobby": + this.lobby(m); + break; + case "game": + break; + } + }, + + handshake: function(m) { + switch (m.type) { + case "verr": + this.soc.close(); + alert(`Error connecting to server: version of client (${this.version}) not accepted.`); + console.error("Error connecting to server: version of client (${this.version}) not accepted."); + console.error(m.data); + return; + case "lobby": + this.state = "lobby"; + this.soc.send("ready", ""); + return; + } + }, + + lobby: function (m) { + switch (m.type) { + case "plist": + this.lob.packList(m.data); + break; + case "glist": + this.lob.gameList(m.data, this.game); + this.game = null; + break; + case "players": + this.lob.players(m.data); + break; + case "gdel": + this.lob.removeGame(m.data); + break; + case "gadd": + this.lob.addGame(m.data); + break; + case "pdel": + this.lob.removePlayer(m.data); + break; + case "padd": + this.lob.addPlayer(m.data); + break; + case "pmove": + this.lob.movePlayer(m.data); + break; + } + }, + + game: function (m) { + switch (m.type) { + + } + }, + + // Reset the lobby and table, then attempt to reopen the connection to the server. + reset: function() { + this.state = "handshake"; + + this.lob.reset(); + this.tab.reset(); + + this.soc.init(); + } +}; diff --git a/scripts/client/client.js b/scripts/client/client.js deleted file mode 100644 index b5dd4bf..0000000 --- a/scripts/client/client.js +++ /dev/null @@ -1,105 +0,0 @@ -// Client acts as the message hub for the whole game. -// WebSocket messages come into Client and Client redirects them to the lobby or table based on the state of the game. -// Client also performs the handshake for first starting the connection and messages everyone if the connection errors or closes. -function Client(serveraddr, game) { - this.state = "handshake"; - - this.soc = new SockWorker(serveraddr, "1", this.cb.bind(this)); - - this.lob = new Lobby(document.getElementsByClassName("lobby")[0], this.soc); - this.tab = new Table(document.getElementsByClassName("table")[0], this.soc); - - this.game = game; -} - -Client.prototype = { - init: function() { - this.soc.init(); - }, - - // Entry point for a message. - // If it's a close message, the - cb: function(m) { - console.log(m); - - if(m.type == "error" || m.type == "closed") { - var t = m.type; - t = t[0].toUpperCase() + t.slice(1) - this.lob.setState(t, "#D00", this.soc.server); - this.tab.handleClose(); - return; - } - - switch(this.state) { - case "handshake": - this.handshake(m); - break; - case "lobby": - this.lobby(m); - break; - case "game": - break; - } - }, - - handshake: function(m) { - switch (m.type) { - case "verr": - this.soc.close(); - alert(`Error connecting to server: version of client (${this.version}) not accepted.`); - console.error("Error connecting to server: version of client (${this.version}) not accepted."); - console.error(m.data); - return; - case "lobby": - this.state = "lobby"; - this.soc.send("ready", ""); - return; - } - }, - - lobby: function (m) { - switch (m.type) { - case "plist": - this.lob.packList(m.data); - break; - case "glist": - this.lob.gameList(m.data, this.game); - this.game = null; - break; - case "players": - this.lob.players(m.data); - break; - case "gdel": - this.lob.removeGame(m.data); - break; - case "gadd": - this.lob.addGame(m.data); - break; - case "pdel": - this.lob.removePlayer(m.data); - break; - case "padd": - this.lob.addPlayer(m.data); - break; - case "pmove": - this.lob.movePlayer(m.data); - break; - } - }, - - game: function (m) { - switch (m.type) { - - } - }, - - // Reset the lobby and table, then attempt to reopen the connection to the server. - reset: function() { - this.state = "handshake"; - - this.lob.reset(); - this.tab.reset(); - - this.soc.init(); - } -}; diff --git a/scripts/client/lobby.js b/scripts/client/lobby.js deleted file mode 100644 index 8d46352..0000000 --- a/scripts/client/lobby.js +++ /dev/null @@ -1,102 +0,0 @@ -// Lobby manages the players and games provided by the server and allows users to join or create their own games. -function Lobby(el){ - this.root = el; - - this.elements = { - status: this.root.getElementsByClassName("status")[0], - addr: this.root.getElementsByClassName("addr")[0], - - stats: { - game: document.getElementById("game"), - packs: document.getElementById("packs"), - online: document.getElementById("online"), - ingame: document.getElementById("ingame"), - pubgame: document.getElementById("pubgame") - }, - - settings: { - name: document.getElementById("name"), - color: document.getElementById("usercolor") - } - }; - - this.top = new TopBar(document.getElementsByClassName("topbar")[0]); - - this.init = false; - this.online = []; - this.games = []; - this.packs = []; - this.players = []; -} - -Lobby.prototype = { - packList: function(data){ - - this.elements.stats.packs.innerText = this.packs.length(); - }, - - gameList: function(data, game){ - - this.elements.stats.pubgame.innerText = this.games.length(); - }, - - players: function(data) { - - this.elements.stats.online.innerText = this.players.length(); - this.init = true; - }, - - addGame: function(data){ - - }, - - removeGame: function(data){ - - }, - - addPlayer: function(data){ - - }, - - movePlayer: function(data){ - - }, - - removePlayer: function(data){ - - }, - - newGameScreen: function(){ - if(this.init) return; - }, - - setState: function(text, color, server){ - this.elements.status.style.backgroundColor = color; - this.elements.status.innerText = text; - this.elements.addr.innerText = server; - this.top.setColor(color); - }, - - reset: function(){ - this.setState("Connecting", "#DA0", this.elements.addr.innerText); - this.init = false; - } -}; - -// ############### -// # TopBar Code # -// ############### - -function TopBar(el) { - this.root = el; - - this.newGame = el.getElementsByClassName("new-game")[0]; - this.mobileSettings = el.getElementsByClassName("mobile-settings")[0]; - this.status = el.getElementsByClassName("status")[0]; -} - -TopBar.prototype = { - setColor: function(color) { - this.status.style.backgroundColor = color; - } -}; diff --git a/scripts/client/message.js b/scripts/client/message.js deleted file mode 100644 index 5e821c4..0000000 --- a/scripts/client/message.js +++ /dev/null @@ -1,14 +0,0 @@ -function Message(type, data){ - this.t = type; - this.d = data; -} - -Message.prototype = { - stringify: function(){ - var dat = this.d - if(typeof dat !== "string"){ - dat = JSON.stringify(dat); - } - return JSON.stringify({type: this.t, data: dat}); - } -}; diff --git a/scripts/client/sock.js b/scripts/client/sock.js deleted file mode 100644 index 78c4195..0000000 --- a/scripts/client/sock.js +++ /dev/null @@ -1,52 +0,0 @@ -function SockWorker(serveraddr, version, callback) { - this.server = serveraddr; - this.version = version; - this.cb = callback; -} - -SockWorker.prototype = { - init: function() { - if(this.server == "" || this.server == null) { - return; - } - try { - this.socket = new WebSocket(this.server); - - this.socket.addEventListener("open", this.o.bind(this)); - this.socket.addEventListener("message", this.msg.bind(this)); - - this.socket.addEventListener("closed", this.c.bind(this)); - this.socket.addEventListener("error", this.err.bind(this)); - } catch (e) { - this.err(); - } - }, - - o: function() { - this.send("version", this.version); - }, - - msg: function(e) { - if(typeof e.data == "string") { - var dat = JSON.parse(e.data) - this.cb(dat); - } - }, - - c: function() { - this.cb({type: "close", data: ""}); - }, - - err: function() { - this.cb({type: "error", data: ""}); - }, - - close: function() { - this.socket.close(); - }, - - send: function(type, data) { - var m = new Message(type, data); - this.socket.send(m.stringify()) - } -}; \ No newline at end of file diff --git a/scripts/client/table.js b/scripts/client/table.js deleted file mode 100644 index 911763a..0000000 --- a/scripts/client/table.js +++ /dev/null @@ -1,16 +0,0 @@ -// Table represents and manages the actual game. It accepts inputs from the server and tries to queries the server when the player makes a move. -function Table(el, soc) { - this.root = el; - this.soc = soc; -} - -Table.prototype = { - - handleClose: function() { - - }, - - reset: function() { - - } -} \ No newline at end of file diff --git a/scripts/libs/discord-rpc.js b/scripts/libs/discord-rpc.js deleted file mode 100644 index b51d10f..0000000 --- a/scripts/libs/discord-rpc.js +++ /dev/null @@ -1,8 +0,0 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.RPC=e():t.RPC=e()}(window,(function(){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)n.d(r,i,function(e){return t[e]}.bind(null,i));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=6)}([function(t,e,n){"use strict";(function(e){let r;try{const{app:t}=n(7);r=t.setAsDefaultProtocolClient.bind(t)}catch(t){try{r=n(8)}catch(t){}}"function"!=typeof r&&(r=()=>!1);t.exports={pid:function(){return void 0!==e?e.pid:null},register:r,uuid:()=>{let t="";for(let e=0;e<32;e+=1){let n;if(8!==e&&12!==e&&16!==e&&20!==e||(t+="-"),12===e)n=4;else{const t=16*Math.random()|0;n=16===e?3&t|0:t}t+=n.toString(16)}return t}}}).call(this,n(1))},function(t,e){var n,r,i=t.exports={};function o(){throw new Error("setTimeout has not been defined")}function s(){throw new Error("clearTimeout has not been defined")}function u(t){if(n===setTimeout)return setTimeout(t,0);if((n===o||!n)&&setTimeout)return n=setTimeout,setTimeout(t,0);try{return n(t,0)}catch(e){try{return n.call(null,t,0)}catch(e){return n.call(this,t,0)}}}!function(){try{n="function"==typeof setTimeout?setTimeout:o}catch(t){n=o}try{r="function"==typeof clearTimeout?clearTimeout:s}catch(t){r=s}}();var a,c=[],f=!1,h=-1;function l(){f&&a&&(f=!1,a.length?c=a.concat(c):h=-1,c.length&&p())}function p(){if(!f){var t=u(l);f=!0;for(var e=c.length;e;){for(a=c,c=[];++h1)for(var n=1;n0&&s.length>i&&!s.warned){s.warned=!0;var a=new Error("Possible EventEmitter memory leak detected. "+s.length+" "+String(e)+" listeners added. Use emitter.setMaxListeners() to increase limit");a.name="MaxListenersExceededWarning",a.emitter=t,a.type=e,a.count=s.length,u=a,console&&console.warn&&console.warn(u)}return t}function l(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function p(t,e,n){var r={fired:!1,wrapFn:void 0,target:t,type:e,listener:n},i=l.bind(r);return i.listener=n,r.wrapFn=i,i}function d(t,e,n){var r=t._events;if(void 0===r)return[];var i=r[e];return void 0===i?[]:"function"==typeof i?n?[i.listener||i]:[i]:n?function(t){for(var e=new Array(t.length),n=0;n0&&(s=e[0]),s instanceof Error)throw s;var u=new Error("Unhandled error."+(s?" ("+s.message+")":""));throw u.context=s,u}var a=i[t];if(void 0===a)return!1;if("function"==typeof a)o(a,this,e);else{var c=a.length,f=_(a,c);for(n=0;n=0;o--)if(n[o]===e||n[o].listener===e){s=n[o].listener,i=o;break}if(i<0)return this;0===i?n.shift():function(t,e){for(;e+1=0;r--)this.removeListener(t,e[r]);return this},u.prototype.listeners=function(t){return d(this,t,!0)},u.prototype.rawListeners=function(t){return d(this,t,!1)},u.listenerCount=function(t,e){return"function"==typeof t.listenerCount?t.listenerCount(e):E.call(t,e)},u.prototype.listenerCount=E,u.prototype.eventNames=function(){return this._eventsCount>0?r(this._events):[]}},function(t,e){var n;n=function(){return this}();try{n=n||new Function("return this")()}catch(t){"object"==typeof window&&(n=window)}t.exports=n},function(t,e,n){"use strict";var r=function(){if("undefined"!=typeof self)return self;if("undefined"!=typeof window)return window;if(void 0!==r)return r;throw new Error("unable to locate global object")}();t.exports=e=r.fetch,e.default=r.fetch.bind(r),e.Headers=r.Headers,e.Request=r.Request,e.Response=r.Response},function(t,e,n){"use strict";function r(t){const e={};for(const n of t)e[n]=n;return e}e.browser="undefined"!=typeof window,e.RPCCommands=r(["DISPATCH","AUTHORIZE","AUTHENTICATE","GET_GUILD","GET_GUILDS","GET_CHANNEL","GET_CHANNELS","GET_RELATIONSHIPS","GET_USER","SUBSCRIBE","UNSUBSCRIBE","SET_USER_VOICE_SETTINGS","SET_USER_VOICE_SETTINGS_2","SELECT_VOICE_CHANNEL","GET_SELECTED_VOICE_CHANNEL","SELECT_TEXT_CHANNEL","GET_VOICE_SETTINGS","SET_VOICE_SETTINGS_2","SET_VOICE_SETTINGS","CAPTURE_SHORTCUT","SET_ACTIVITY","SEND_ACTIVITY_JOIN_INVITE","CLOSE_ACTIVITY_JOIN_REQUEST","ACTIVITY_INVITE_USER","ACCEPT_ACTIVITY_INVITE","INVITE_BROWSER","DEEP_LINK","CONNECTIONS_CALLBACK","BRAINTREE_POPUP_BRIDGE_CALLBACK","GIFT_CODE_BROWSER","OVERLAY","BROWSER_HANDOFF","SET_CERTIFIED_DEVICES","GET_IMAGE","CREATE_LOBBY","UPDATE_LOBBY","DELETE_LOBBY","UPDATE_LOBBY_MEMBER","CONNECT_TO_LOBBY","DISCONNECT_FROM_LOBBY","SEND_TO_LOBBY","SEARCH_LOBBIES","CONNECT_TO_LOBBY_VOICE","DISCONNECT_FROM_LOBBY_VOICE","SET_OVERLAY_LOCKED","OPEN_OVERLAY_ACTIVITY_INVITE","OPEN_OVERLAY_GUILD_INVITE","OPEN_OVERLAY_VOICE_SETTINGS","VALIDATE_APPLICATION","GET_ENTITLEMENT_TICKET","GET_APPLICATION_TICKET","START_PURCHASE","GET_SKUS","GET_ENTITLEMENTS","GET_NETWORKING_CONFIG","NETWORKING_SYSTEM_METRICS","NETWORKING_PEER_METRICS","NETWORKING_CREATE_TOKEN","SET_USER_ACHIEVEMENT","GET_USER_ACHIEVEMENTS"]),e.RPCEvents=r(["CURRENT_USER_UPDATE","GUILD_STATUS","GUILD_CREATE","CHANNEL_CREATE","RELATIONSHIP_UPDATE","VOICE_CHANNEL_SELECT","VOICE_STATE_CREATE","VOICE_STATE_DELETE","VOICE_STATE_UPDATE","VOICE_SETTINGS_UPDATE","VOICE_SETTINGS_UPDATE_2","VOICE_CONNECTION_STATUS","SPEAKING_START","SPEAKING_STOP","GAME_JOIN","GAME_SPECTATE","ACTIVITY_JOIN","ACTIVITY_JOIN_REQUEST","ACTIVITY_SPECTATE","ACTIVITY_INVITE","NOTIFICATION_CREATE","MESSAGE_CREATE","MESSAGE_UPDATE","MESSAGE_DELETE","LOBBY_DELETE","LOBBY_UPDATE","LOBBY_MEMBER_CONNECT","LOBBY_MEMBER_DISCONNECT","LOBBY_MEMBER_UPDATE","LOBBY_MESSAGE","CAPTURE_SHORTCUT_CHANGE","OVERLAY","OVERLAY_UPDATE","ENTITLEMENT_CREATE","ENTITLEMENT_DELETE","USER_ACHIEVEMENT_UPDATE","READY","ERROR"]),e.RPCErrors={CAPTURE_SHORTCUT_ALREADY_LISTENING:5004,GET_GUILD_TIMED_OUT:5002,INVALID_ACTIVITY_JOIN_REQUEST:4012,INVALID_ACTIVITY_SECRET:5005,INVALID_CHANNEL:4005,INVALID_CLIENTID:4007,INVALID_COMMAND:4002,INVALID_ENTITLEMENT:4015,INVALID_EVENT:4004,INVALID_GIFT_CODE:4016,INVALID_GUILD:4003,INVALID_INVITE:4011,INVALID_LOBBY:4013,INVALID_LOBBY_SECRET:4014,INVALID_ORIGIN:4008,INVALID_PAYLOAD:4e3,INVALID_PERMISSIONS:4006,INVALID_TOKEN:4009,INVALID_USER:4010,LOBBY_FULL:5007,NO_ELIGIBLE_ACTIVITY:5006,OAUTH2_ERROR:5e3,PURCHASE_CANCELED:5008,PURCHASE_ERROR:5009,RATE_LIMITED:5011,SELECT_CHANNEL_TIMED_OUT:5001,SELECT_VOICE_FORCE_REQUIRED:5003,SERVICE_UNAVAILABLE:1001,TRANSACTION_ABORTED:1002,UNAUTHORIZED_FOR_ACHIEVEMENT:5010,UNKNOWN_ERROR:1e3},e.RPCCloseCodes={CLOSE_NORMAL:1e3,CLOSE_UNSUPPORTED:1003,CLOSE_ABNORMAL:1006,INVALID_CLIENTID:4e3,INVALID_ORIGIN:4001,RATELIMITED:4002,TOKEN_REVOKED:4003,INVALID_VERSION:4004,INVALID_ENCODING:4005},e.LobbyTypes={PRIVATE:1,PUBLIC:2},e.RelationshipTypes={NONE:0,FRIEND:1,BLOCKED:2,PENDING_INCOMING:3,PENDING_OUTGOING:4,IMPLICIT:5}},function(t,e,n){"use strict";const r=n(0);t.exports={Client:n(9),register:t=>r.register(`discord-${t}`)}},function(t,e){},function(t,e){},function(t,e,n){"use strict";const r=n(2),{setTimeout:i,clearTimeout:o}=n(10),s=n(4),u=n(12),{RPCCommands:a,RPCEvents:c,RelationshipTypes:f}=n(5),{pid:h,uuid:l}=n(0);function p(t,e){return`${t}${JSON.stringify(e)}`}t.exports=class extends r{constructor(t={}){super(),this.options=t,this.accessToken=null,this.clientId=null,this.application=null,this.user=null;const e=u[t.transport];if(!e)throw new TypeError("RPC_INVALID_TRANSPORT",t.transport);this.fetch=(t,e,{data:n,query:r}={})=>s(`${this.fetch.endpoint}${e}${r?new URLSearchParams(r):""}`,{method:t,body:n,headers:{Authorization:`Bearer ${this.accessToken}`}}).then(t=>t.json()),this.fetch.endpoint="https://discordapp.com/api",this.transport=new e(this),this.transport.on("message",this._onRpcMessage.bind(this)),this._expecting=new Map,this._subscriptions=new Map,this._connectPromise=void 0}connect(t){return this._connectPromise||(this.clientId=t,this._connectPromise=new Promise((e,n)=>{this.clientId=t;const r=i(()=>n(new Error("RPC_CONNECTION_TIMEOUT")),1e4);r.unref(),this.once("connected",()=>{o(r),e(this)}),this.transport.once("close",()=>{this._expecting.forEach(t=>{t.reject(new Error("connection closed"))}),this.emit("disconnected"),n()}),this.transport.connect().catch(n)})),this._connectPromise}async login(t={}){let{clientId:e,accessToken:n}=t;return await this.connect(e),t.scopes?(n||(n=await this.authorize(t)),this.authenticate(n)):(this.emit("ready"),this)}request(t,e,n){return new Promise((r,i)=>{const o=l();this.transport.send({cmd:t,args:e,evt:n,nonce:o}),this._expecting.set(o,{resolve:r,reject:i})})}_onRpcMessage(t){if(t.cmd===a.DISPATCH&&t.evt===c.READY)t.data.user&&(this.user=t.data.user),this.emit("connected");else if(this._expecting.has(t.nonce)){const{resolve:e,reject:n}=this._expecting.get(t.nonce);if("ERROR"===t.evt){const e=new Error(t.data.message);e.code=t.data.code,e.data=t.data,n(e)}else e(t.data);this._expecting.delete(t.nonce)}else{const e=p(t.evt,t.args);if(!this._subscriptions.has(e))return;this._subscriptions.get(e)(t.data)}}async authorize({scopes:t,clientSecret:e,rpcToken:n,redirectUri:r}={}){if(e&&!0===n){n=(await this.fetch("POST","/oauth2/token/rpc",{data:new URLSearchParams({client_id:this.clientId,client_secret:e})})).rpc_token}const{code:i}=await this.request("AUTHORIZE",{scopes:t,client_id:this.clientId,rpc_token:n,redirect_uri:r});return(await this.fetch("POST","/oauth2/token",{data:new URLSearchParams({client_id:this.clientId,client_secret:e,code:i,grant_type:"authorization_code",redirect_uri:r})})).access_token}authenticate(t){return this.request("AUTHENTICATE",{access_token:t}).then(({application:e,user:n})=>(this.accessToken=t,this.application=e,this.user=n,this.emit("ready"),this))}getGuild(t,e){return this.request(a.GET_GUILD,{guild_id:t,timeout:e})}getGuilds(t){return this.request(a.GET_GUILDS,{timeout:t})}getChannel(t,e){return this.request(a.GET_CHANNEL,{channel_id:t,timeout:e})}async getChannels(t,e){const{channels:n}=await this.request(a.GET_CHANNELS,{timeout:e,guild_id:t});return n}setCertifiedDevices(t){return this.request(a.SET_CERTIFIED_DEVICES,{devices:t.map(t=>({type:t.type,id:t.uuid,vendor:t.vendor,model:t.model,related:t.related,echo_cancellation:t.echoCancellation,noise_suppression:t.noiseSuppression,automatic_gain_control:t.automaticGainControl,hardware_mute:t.hardwareMute}))})}setUserVoiceSettings(t,e){return this.request(a.SET_USER_VOICE_SETTINGS,{user_id:t,pan:e.pan,mute:e.mute,volume:e.volume})}selectVoiceChannel(t,{timeout:e,force:n=!1}={}){return this.request(a.SELECT_VOICE_CHANNEL,{channel_id:t,timeout:e,force:n})}selectTextChannel(t,{timeout:e,force:n=!1}={}){return this.request(a.SELECT_TEXT_CHANNEL,{channel_id:t,timeout:e,force:n})}getVoiceSettings(){return this.request(a.GET_VOICE_SETTINGS).then(t=>({automaticGainControl:t.automatic_gain_control,echoCancellation:t.echo_cancellation,noiseSuppression:t.noise_suppression,qos:t.qos,silenceWarning:t.silence_warning,deaf:t.deaf,mute:t.mute,input:{availableDevices:t.input.available_devices,device:t.input.device_id,volume:t.input.volume},output:{availableDevices:t.output.available_devices,device:t.output.device_id,volume:t.output.volume},mode:{type:t.mode.type,autoThreshold:t.mode.auto_threshold,threshold:t.mode.threshold,shortcut:t.mode.shortcut,delay:t.mode.delay}}))}setVoiceSettings(t){return this.request(a.SET_VOICE_SETTINGS,{automatic_gain_control:t.automaticGainControl,echo_cancellation:t.echoCancellation,noise_suppression:t.noiseSuppression,qos:t.qos,silence_warning:t.silenceWarning,deaf:t.deaf,mute:t.mute,input:t.input?{device_id:t.input.device,volume:t.input.volume}:void 0,output:t.output?{device_id:t.output.device,volume:t.output.volume}:void 0,mode:t.mode?{mode:t.mode.type,auto_threshold:t.mode.autoThreshold,threshold:t.mode.threshold,shortcut:t.mode.shortcut,delay:t.mode.delay}:void 0})}captureShortcut(t){const e=p(c.CAPTURE_SHORTCUT_CHANGE),n=()=>(this._subscriptions.delete(e),this.request(a.CAPTURE_SHORTCUT,{action:"STOP"}));return this._subscriptions.set(e,({shortcut:e})=>{t(e,n)}),this.request(a.CAPTURE_SHORTCUT,{action:"START"}).then(()=>n)}setActivity(t={},e=h()){let n,r,i,o;if(t.startTimestamp||t.endTimestamp){if(n={start:t.startTimestamp,end:t.endTimestamp},n.start instanceof Date&&(n.start=Math.round(n.start.getTime())),n.end instanceof Date&&(n.end=Math.round(n.end.getTime())),n.start>2147483647e3)throw new RangeError("timestamps.start must fit into a unix timestamp");if(n.end>2147483647e3)throw new RangeError("timestamps.end must fit into a unix timestamp")}return(t.largeImageKey||t.largeImageText||t.smallImageKey||t.smallImageText)&&(r={large_image:t.largeImageKey,large_text:t.largeImageText,small_image:t.smallImageKey,small_text:t.smallImageText}),(t.partySize||t.partyId||t.partyMax)&&(i={id:t.partyId},(t.partySize||t.partyMax)&&(i.size=[t.partySize,t.partyMax])),(t.matchSecret||t.joinSecret||t.spectateSecret)&&(o={match:t.matchSecret,join:t.joinSecret,spectate:t.spectateSecret}),this.request(a.SET_ACTIVITY,{pid:e,activity:{state:t.state,details:t.details,timestamps:n,assets:r,party:i,secrets:o,instance:!!t.instance}})}clearActivity(t=h()){return this.request(a.SET_ACTIVITY,{pid:t})}sendJoinInvite(t){return this.request(a.SEND_ACTIVITY_JOIN_INVITE,{user_id:t.id||t})}sendJoinRequest(t){return this.request(a.SEND_ACTIVITY_JOIN_REQUEST,{user_id:t.id||t})}closeJoinRequest(t){return this.request(a.CLOSE_ACTIVITY_JOIN_REQUEST,{user_id:t.id||t})}createLobby(t,e,n){return this.request(a.CREATE_LOBBY,{type:t,capacity:e,metadata:n})}updateLobby(t,{type:e,owner:n,capacity:r,metadata:i}={}){return this.request(a.UPDATE_LOBBY,{id:t.id||t,type:e,owner_id:n&&n.id||n,capacity:r,metadata:i})}deleteLobby(t){return this.request(a.DELETE_LOBBY,{id:t.id||t})}connectToLobby(t,e){return this.request(a.CONNECT_TO_LOBBY,{id:t,secret:e})}sendToLobby(t,e){return this.request(a.SEND_TO_LOBBY,{id:t.id||t,data:e})}disconnectFromLobby(t){return this.request(a.DISCONNECT_FROM_LOBBY,{id:t.id||t})}updateLobbyMember(t,e,n){return this.request(a.UPDATE_LOBBY_MEMBER,{lobby_id:t.id||t,user_id:e.id||e,metadata:n})}getRelationships(){const t=Object.keys(f);return this.request(a.GET_RELATIONSHIPS).then(e=>e.relationships.map(e=>({...e,type:t[e.type]})))}subscribe(t,e,n){return n||"function"!=typeof e||(n=e,e=void 0),this.request(a.SUBSCRIBE,e,t).then(()=>{const r=p(t,e);return this._subscriptions.set(r,n),{unsubscribe:()=>this.request(a.UNSUBSCRIBE,e,t).then(()=>this._subscriptions.delete(r))}})}async destroy(){this.transport.close()}}},function(t,e,n){(function(t){var r=void 0!==t&&t||"undefined"!=typeof self&&self||window,i=Function.prototype.apply;function o(t,e){this._id=t,this._clearFn=e}e.setTimeout=function(){return new o(i.call(setTimeout,r,arguments),clearTimeout)},e.setInterval=function(){return new o(i.call(setInterval,r,arguments),clearInterval)},e.clearTimeout=e.clearInterval=function(t){t&&t.close()},o.prototype.unref=o.prototype.ref=function(){},o.prototype.close=function(){this._clearFn.call(r,this._id)},e.enroll=function(t,e){clearTimeout(t._idleTimeoutId),t._idleTimeout=e},e.unenroll=function(t){clearTimeout(t._idleTimeoutId),t._idleTimeout=-1},e._unrefActive=e.active=function(t){clearTimeout(t._idleTimeoutId);var e=t._idleTimeout;e>=0&&(t._idleTimeoutId=setTimeout((function(){t._onTimeout&&t._onTimeout()}),e))},n(11),e.setImmediate="undefined"!=typeof self&&self.setImmediate||void 0!==t&&t.setImmediate||this&&this.setImmediate,e.clearImmediate="undefined"!=typeof self&&self.clearImmediate||void 0!==t&&t.clearImmediate||this&&this.clearImmediate}).call(this,n(3))},function(t,e,n){(function(t,e){!function(t,n){"use strict";if(!t.setImmediate){var r,i,o,s,u,a=1,c={},f=!1,h=t.document,l=Object.getPrototypeOf&&Object.getPrototypeOf(t);l=l&&l.setTimeout?l:t,"[object process]"==={}.toString.call(t.process)?r=function(t){e.nextTick((function(){d(t)}))}:!function(){if(t.postMessage&&!t.importScripts){var e=!0,n=t.onmessage;return t.onmessage=function(){e=!1},t.postMessage("","*"),t.onmessage=n,e}}()?t.MessageChannel?((o=new MessageChannel).port1.onmessage=function(t){d(t.data)},r=function(t){o.port2.postMessage(t)}):h&&"onreadystatechange"in h.createElement("script")?(i=h.documentElement,r=function(t){var e=h.createElement("script");e.onreadystatechange=function(){d(t),e.onreadystatechange=null,i.removeChild(e),e=null},i.appendChild(e)}):r=function(t){setTimeout(d,0,t)}:(s="setImmediate$"+Math.random()+"$",u=function(e){e.source===t&&"string"==typeof e.data&&0===e.data.indexOf(s)&&d(+e.data.slice(s.length))},t.addEventListener?t.addEventListener("message",u,!1):t.attachEvent("onmessage",u),r=function(e){t.postMessage(s+e,"*")}),l.setImmediate=function(t){"function"!=typeof t&&(t=new Function(""+t));for(var e=new Array(arguments.length-1),n=0;n{const o=function(t){if("win32"===e.platform)return`\\\\?\\pipe\\discord-ipc-${t}`;const{env:{XDG_RUNTIME_DIR:n,TMPDIR:r,TMP:i,TEMP:o}}=e;return`${(n||r||i||o||"/tmp").replace(/\/$/,"")}/discord-ipc-${t}`}(t),s=()=>{t<10?n(p(t+1)):r(new Error("Could not connect"))},u=i.createConnection(o,()=>{u.removeListener("error",s),n(u)});u.once("error",s)})}function d(t,e){e=JSON.stringify(e);const n=r.byteLength(e),i=r.alloc(8+n);return i.writeInt32LE(t,0),i.writeInt32LE(n,4),i.write(e,8,n),i}const E={full:"",op:void 0};function _(t,e){const n=t.read();if(!n)return;let r,{op:i}=E;if(""===E.full){i=E.op=n.readInt32LE(0);const t=n.readInt32LE(4);r=n.slice(8,t+8)}else r=n.toString();try{e({op:i,data:JSON.parse(E.full+r)}),E.full="",E.op=void 0}catch(t){E.full+=r}_(t,e)}t.exports=class extends o{constructor(t){super(),this.client=t,this.socket=null}async connect(){const t=this.socket=await p();t.on("close",this.onClose.bind(this)),t.on("error",this.onClose.bind(this)),this.emit("open"),t.write(d(a,{v:1,client_id:this.client.clientId})),t.pause(),t.on("readable",()=>{_(t,({op:t,data:e})=>{switch(t){case h:this.send(e,l);break;case c:if(!e)return;"AUTHORIZE"===e.cmd&&"ERROR"!==e.evt&&async function t(e=0){if(e>30)throw new Error("Could not find endpoint");const n=`http://127.0.0.1:${6463+e%10}`;try{return 401!==(await s(n)).status?t(e+1):n}catch(n){return t(e+1)}}().then(t=>{this.client.request.endpoint=t}),this.emit("message",e);break;case f:this.emit("close",e)}})})}onClose(t){this.emit("close",t)}send(t,e=c){this.socket.write(d(e,t))}close(){this.send({},f),this.socket.end()}ping(){this.send(u(),h)}},t.exports.encode=d,t.exports.decode=_}).call(this,n(1),n(14).Buffer)},function(t,e,n){"use strict";(function(t){ -/*! - * The buffer module from node.js, for the browser. - * - * @author Feross Aboukhadijeh - * @license MIT - */ -var r=n(15),i=n(16),o=n(17);function s(){return a.TYPED_ARRAY_SUPPORT?2147483647:1073741823}function u(t,e){if(s()=s())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+s().toString(16)+" bytes");return 0|t}function d(t,e){if(a.isBuffer(t))return t.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(t)||t instanceof ArrayBuffer))return t.byteLength;"string"!=typeof t&&(t=""+t);var n=t.length;if(0===n)return 0;for(var r=!1;;)switch(e){case"ascii":case"latin1":case"binary":return n;case"utf8":case"utf-8":case void 0:return G(t).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*n;case"hex":return n>>>1;case"base64":return k(t).length;default:if(r)return G(t).length;e=(""+e).toLowerCase(),r=!0}}function E(t,e,n){var r=!1;if((void 0===e||e<0)&&(e=0),e>this.length)return"";if((void 0===n||n>this.length)&&(n=this.length),n<=0)return"";if((n>>>=0)<=(e>>>=0))return"";for(t||(t="utf8");;)switch(t){case"hex":return L(this,e,n);case"utf8":case"utf-8":return C(this,e,n);case"ascii":return S(this,e,n);case"latin1":case"binary":return O(this,e,n);case"base64":return R(this,e,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return N(this,e,n);default:if(r)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),r=!0}}function _(t,e,n){var r=t[e];t[e]=t[n],t[n]=r}function T(t,e,n,r,i){if(0===t.length)return-1;if("string"==typeof n?(r=n,n=0):n>2147483647?n=2147483647:n<-2147483648&&(n=-2147483648),n=+n,isNaN(n)&&(n=i?0:t.length-1),n<0&&(n=t.length+n),n>=t.length){if(i)return-1;n=t.length-1}else if(n<0){if(!i)return-1;n=0}if("string"==typeof e&&(e=a.from(e,r)),a.isBuffer(e))return 0===e.length?-1:g(t,e,n,r,i);if("number"==typeof e)return e&=255,a.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(t,e,n):Uint8Array.prototype.lastIndexOf.call(t,e,n):g(t,[e],n,r,i);throw new TypeError("val must be string, number or Buffer")}function g(t,e,n,r,i){var o,s=1,u=t.length,a=e.length;if(void 0!==r&&("ucs2"===(r=String(r).toLowerCase())||"ucs-2"===r||"utf16le"===r||"utf-16le"===r)){if(t.length<2||e.length<2)return-1;s=2,u/=2,a/=2,n/=2}function c(t,e){return 1===s?t[e]:t.readUInt16BE(e*s)}if(i){var f=-1;for(o=n;ou&&(n=u-a),o=n;o>=0;o--){for(var h=!0,l=0;li&&(r=i):r=i;var o=e.length;if(o%2!=0)throw new TypeError("Invalid hex string");r>o/2&&(r=o/2);for(var s=0;s>8,i=n%256,o.push(i),o.push(r);return o}(e,t.length-n),t,n,r)}function R(t,e,n){return 0===e&&n===t.length?r.fromByteArray(t):r.fromByteArray(t.slice(e,n))}function C(t,e,n){n=Math.min(t.length,n);for(var r=[],i=e;i239?4:c>223?3:c>191?2:1;if(i+h<=n)switch(h){case 1:c<128&&(f=c);break;case 2:128==(192&(o=t[i+1]))&&(a=(31&c)<<6|63&o)>127&&(f=a);break;case 3:o=t[i+1],s=t[i+2],128==(192&o)&&128==(192&s)&&(a=(15&c)<<12|(63&o)<<6|63&s)>2047&&(a<55296||a>57343)&&(f=a);break;case 4:o=t[i+1],s=t[i+2],u=t[i+3],128==(192&o)&&128==(192&s)&&128==(192&u)&&(a=(15&c)<<18|(63&o)<<12|(63&s)<<6|63&u)>65535&&a<1114112&&(f=a)}null===f?(f=65533,h=1):f>65535&&(f-=65536,r.push(f>>>10&1023|55296),f=56320|1023&f),r.push(f),i+=h}return function(t){var e=t.length;if(e<=4096)return String.fromCharCode.apply(String,t);var n="",r=0;for(;r0&&(t=this.toString("hex",0,n).match(/.{2}/g).join(" "),this.length>n&&(t+=" ... ")),""},a.prototype.compare=function(t,e,n,r,i){if(!a.isBuffer(t))throw new TypeError("Argument must be a Buffer");if(void 0===e&&(e=0),void 0===n&&(n=t?t.length:0),void 0===r&&(r=0),void 0===i&&(i=this.length),e<0||n>t.length||r<0||i>this.length)throw new RangeError("out of range index");if(r>=i&&e>=n)return 0;if(r>=i)return-1;if(e>=n)return 1;if(this===t)return 0;for(var o=(i>>>=0)-(r>>>=0),s=(n>>>=0)-(e>>>=0),u=Math.min(o,s),c=this.slice(r,i),f=t.slice(e,n),h=0;hi)&&(n=i),t.length>0&&(n<0||e<0)||e>this.length)throw new RangeError("Attempt to write outside buffer bounds");r||(r="utf8");for(var o=!1;;)switch(r){case"hex":return y(this,t,e,n);case"utf8":case"utf-8":return m(this,t,e,n);case"ascii":return I(this,t,e,n);case"latin1":case"binary":return v(this,t,e,n);case"base64":return A(this,t,e,n);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return w(this,t,e,n);default:if(o)throw new TypeError("Unknown encoding: "+r);r=(""+r).toLowerCase(),o=!0}},a.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};function S(t,e,n){var r="";n=Math.min(t.length,n);for(var i=e;ir)&&(n=r);for(var i="",o=e;on)throw new RangeError("Trying to access beyond buffer length")}function P(t,e,n,r,i,o){if(!a.isBuffer(t))throw new TypeError('"buffer" argument must be a Buffer instance');if(e>i||et.length)throw new RangeError("Index out of range")}function U(t,e,n,r){e<0&&(e=65535+e+1);for(var i=0,o=Math.min(t.length-n,2);i>>8*(r?i:1-i)}function B(t,e,n,r){e<0&&(e=4294967295+e+1);for(var i=0,o=Math.min(t.length-n,4);i>>8*(r?i:3-i)&255}function D(t,e,n,r,i,o){if(n+r>t.length)throw new RangeError("Index out of range");if(n<0)throw new RangeError("Index out of range")}function M(t,e,n,r,o){return o||D(t,0,n,4),i.write(t,e,n,r,23,4),n+4}function Y(t,e,n,r,o){return o||D(t,0,n,8),i.write(t,e,n,r,52,8),n+8}a.prototype.slice=function(t,e){var n,r=this.length;if((t=~~t)<0?(t+=r)<0&&(t=0):t>r&&(t=r),(e=void 0===e?r:~~e)<0?(e+=r)<0&&(e=0):e>r&&(e=r),e0&&(i*=256);)r+=this[t+--e]*i;return r},a.prototype.readUInt8=function(t,e){return e||b(t,1,this.length),this[t]},a.prototype.readUInt16LE=function(t,e){return e||b(t,2,this.length),this[t]|this[t+1]<<8},a.prototype.readUInt16BE=function(t,e){return e||b(t,2,this.length),this[t]<<8|this[t+1]},a.prototype.readUInt32LE=function(t,e){return e||b(t,4,this.length),(this[t]|this[t+1]<<8|this[t+2]<<16)+16777216*this[t+3]},a.prototype.readUInt32BE=function(t,e){return e||b(t,4,this.length),16777216*this[t]+(this[t+1]<<16|this[t+2]<<8|this[t+3])},a.prototype.readIntLE=function(t,e,n){t|=0,e|=0,n||b(t,e,this.length);for(var r=this[t],i=1,o=0;++o=(i*=128)&&(r-=Math.pow(2,8*e)),r},a.prototype.readIntBE=function(t,e,n){t|=0,e|=0,n||b(t,e,this.length);for(var r=e,i=1,o=this[t+--r];r>0&&(i*=256);)o+=this[t+--r]*i;return o>=(i*=128)&&(o-=Math.pow(2,8*e)),o},a.prototype.readInt8=function(t,e){return e||b(t,1,this.length),128&this[t]?-1*(255-this[t]+1):this[t]},a.prototype.readInt16LE=function(t,e){e||b(t,2,this.length);var n=this[t]|this[t+1]<<8;return 32768&n?4294901760|n:n},a.prototype.readInt16BE=function(t,e){e||b(t,2,this.length);var n=this[t+1]|this[t]<<8;return 32768&n?4294901760|n:n},a.prototype.readInt32LE=function(t,e){return e||b(t,4,this.length),this[t]|this[t+1]<<8|this[t+2]<<16|this[t+3]<<24},a.prototype.readInt32BE=function(t,e){return e||b(t,4,this.length),this[t]<<24|this[t+1]<<16|this[t+2]<<8|this[t+3]},a.prototype.readFloatLE=function(t,e){return e||b(t,4,this.length),i.read(this,t,!0,23,4)},a.prototype.readFloatBE=function(t,e){return e||b(t,4,this.length),i.read(this,t,!1,23,4)},a.prototype.readDoubleLE=function(t,e){return e||b(t,8,this.length),i.read(this,t,!0,52,8)},a.prototype.readDoubleBE=function(t,e){return e||b(t,8,this.length),i.read(this,t,!1,52,8)},a.prototype.writeUIntLE=function(t,e,n,r){(t=+t,e|=0,n|=0,r)||P(this,t,e,n,Math.pow(2,8*n)-1,0);var i=1,o=0;for(this[e]=255&t;++o=0&&(o*=256);)this[e+i]=t/o&255;return e+n},a.prototype.writeUInt8=function(t,e,n){return t=+t,e|=0,n||P(this,t,e,1,255,0),a.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),this[e]=255&t,e+1},a.prototype.writeUInt16LE=function(t,e,n){return t=+t,e|=0,n||P(this,t,e,2,65535,0),a.TYPED_ARRAY_SUPPORT?(this[e]=255&t,this[e+1]=t>>>8):U(this,t,e,!0),e+2},a.prototype.writeUInt16BE=function(t,e,n){return t=+t,e|=0,n||P(this,t,e,2,65535,0),a.TYPED_ARRAY_SUPPORT?(this[e]=t>>>8,this[e+1]=255&t):U(this,t,e,!1),e+2},a.prototype.writeUInt32LE=function(t,e,n){return t=+t,e|=0,n||P(this,t,e,4,4294967295,0),a.TYPED_ARRAY_SUPPORT?(this[e+3]=t>>>24,this[e+2]=t>>>16,this[e+1]=t>>>8,this[e]=255&t):B(this,t,e,!0),e+4},a.prototype.writeUInt32BE=function(t,e,n){return t=+t,e|=0,n||P(this,t,e,4,4294967295,0),a.TYPED_ARRAY_SUPPORT?(this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t):B(this,t,e,!1),e+4},a.prototype.writeIntLE=function(t,e,n,r){if(t=+t,e|=0,!r){var i=Math.pow(2,8*n-1);P(this,t,e,n,i-1,-i)}var o=0,s=1,u=0;for(this[e]=255&t;++o>0)-u&255;return e+n},a.prototype.writeIntBE=function(t,e,n,r){if(t=+t,e|=0,!r){var i=Math.pow(2,8*n-1);P(this,t,e,n,i-1,-i)}var o=n-1,s=1,u=0;for(this[e+o]=255&t;--o>=0&&(s*=256);)t<0&&0===u&&0!==this[e+o+1]&&(u=1),this[e+o]=(t/s>>0)-u&255;return e+n},a.prototype.writeInt8=function(t,e,n){return t=+t,e|=0,n||P(this,t,e,1,127,-128),a.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),t<0&&(t=255+t+1),this[e]=255&t,e+1},a.prototype.writeInt16LE=function(t,e,n){return t=+t,e|=0,n||P(this,t,e,2,32767,-32768),a.TYPED_ARRAY_SUPPORT?(this[e]=255&t,this[e+1]=t>>>8):U(this,t,e,!0),e+2},a.prototype.writeInt16BE=function(t,e,n){return t=+t,e|=0,n||P(this,t,e,2,32767,-32768),a.TYPED_ARRAY_SUPPORT?(this[e]=t>>>8,this[e+1]=255&t):U(this,t,e,!1),e+2},a.prototype.writeInt32LE=function(t,e,n){return t=+t,e|=0,n||P(this,t,e,4,2147483647,-2147483648),a.TYPED_ARRAY_SUPPORT?(this[e]=255&t,this[e+1]=t>>>8,this[e+2]=t>>>16,this[e+3]=t>>>24):B(this,t,e,!0),e+4},a.prototype.writeInt32BE=function(t,e,n){return t=+t,e|=0,n||P(this,t,e,4,2147483647,-2147483648),t<0&&(t=4294967295+t+1),a.TYPED_ARRAY_SUPPORT?(this[e]=t>>>24,this[e+1]=t>>>16,this[e+2]=t>>>8,this[e+3]=255&t):B(this,t,e,!1),e+4},a.prototype.writeFloatLE=function(t,e,n){return M(this,t,e,!0,n)},a.prototype.writeFloatBE=function(t,e,n){return M(this,t,e,!1,n)},a.prototype.writeDoubleLE=function(t,e,n){return Y(this,t,e,!0,n)},a.prototype.writeDoubleBE=function(t,e,n){return Y(this,t,e,!1,n)},a.prototype.copy=function(t,e,n,r){if(n||(n=0),r||0===r||(r=this.length),e>=t.length&&(e=t.length),e||(e=0),r>0&&r=this.length)throw new RangeError("sourceStart out of bounds");if(r<0)throw new RangeError("sourceEnd out of bounds");r>this.length&&(r=this.length),t.length-e=0;--i)t[i+e]=this[i+n];else if(o<1e3||!a.TYPED_ARRAY_SUPPORT)for(i=0;i>>=0,n=void 0===n?this.length:n>>>0,t||(t=0),"number"==typeof t)for(o=e;o55295&&n<57344){if(!i){if(n>56319){(e-=3)>-1&&o.push(239,191,189);continue}if(s+1===r){(e-=3)>-1&&o.push(239,191,189);continue}i=n;continue}if(n<56320){(e-=3)>-1&&o.push(239,191,189),i=n;continue}n=65536+(i-55296<<10|n-56320)}else i&&(e-=3)>-1&&o.push(239,191,189);if(i=null,n<128){if((e-=1)<0)break;o.push(n)}else if(n<2048){if((e-=2)<0)break;o.push(n>>6|192,63&n|128)}else if(n<65536){if((e-=3)<0)break;o.push(n>>12|224,n>>6&63|128,63&n|128)}else{if(!(n<1114112))throw new Error("Invalid code point");if((e-=4)<0)break;o.push(n>>18|240,n>>12&63|128,n>>6&63|128,63&n|128)}}return o}function k(t){return r.toByteArray(function(t){if((t=function(t){return t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")}(t).replace(V,"")).length<2)return"";for(;t.length%4!=0;)t+="=";return t}(t))}function j(t,e,n,r){for(var i=0;i=e.length||i>=t.length);++i)e[i+n]=t[i];return i}}).call(this,n(3))},function(t,e,n){"use strict";e.byteLength=function(t){var e=c(t),n=e[0],r=e[1];return 3*(n+r)/4-r},e.toByteArray=function(t){var e,n,r=c(t),s=r[0],u=r[1],a=new o(function(t,e,n){return 3*(e+n)/4-n}(0,s,u)),f=0,h=u>0?s-4:s;for(n=0;n>16&255,a[f++]=e>>8&255,a[f++]=255&e;2===u&&(e=i[t.charCodeAt(n)]<<2|i[t.charCodeAt(n+1)]>>4,a[f++]=255&e);1===u&&(e=i[t.charCodeAt(n)]<<10|i[t.charCodeAt(n+1)]<<4|i[t.charCodeAt(n+2)]>>2,a[f++]=e>>8&255,a[f++]=255&e);return a},e.fromByteArray=function(t){for(var e,n=t.length,i=n%3,o=[],s=0,u=n-i;su?u:s+16383));1===i?(e=t[n-1],o.push(r[e>>2]+r[e<<4&63]+"==")):2===i&&(e=(t[n-2]<<8)+t[n-1],o.push(r[e>>10]+r[e>>4&63]+r[e<<2&63]+"="));return o.join("")};for(var r=[],i=[],o="undefined"!=typeof Uint8Array?Uint8Array:Array,s="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",u=0,a=s.length;u0)throw new Error("Invalid string. Length must be a multiple of 4");var n=t.indexOf("=");return-1===n&&(n=e),[n,n===e?0:4-n%4]}function f(t,e,n){for(var i,o,s=[],u=e;u>18&63]+r[o>>12&63]+r[o>>6&63]+r[63&o]);return s.join("")}i["-".charCodeAt(0)]=62,i["_".charCodeAt(0)]=63},function(t,e){e.read=function(t,e,n,r,i){var o,s,u=8*i-r-1,a=(1<>1,f=-7,h=n?i-1:0,l=n?-1:1,p=t[e+h];for(h+=l,o=p&(1<<-f)-1,p>>=-f,f+=u;f>0;o=256*o+t[e+h],h+=l,f-=8);for(s=o&(1<<-f)-1,o>>=-f,f+=r;f>0;s=256*s+t[e+h],h+=l,f-=8);if(0===o)o=1-c;else{if(o===a)return s?NaN:1/0*(p?-1:1);s+=Math.pow(2,r),o-=c}return(p?-1:1)*s*Math.pow(2,o-r)},e.write=function(t,e,n,r,i,o){var s,u,a,c=8*o-i-1,f=(1<>1,l=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,p=r?0:o-1,d=r?1:-1,E=e<0||0===e&&1/e<0?1:0;for(e=Math.abs(e),isNaN(e)||e===1/0?(u=isNaN(e)?1:0,s=f):(s=Math.floor(Math.log(e)/Math.LN2),e*(a=Math.pow(2,-s))<1&&(s--,a*=2),(e+=s+h>=1?l/a:l*Math.pow(2,1-h))*a>=2&&(s++,a/=2),s+h>=f?(u=0,s=f):s+h>=1?(u=(e*a-1)*Math.pow(2,i),s+=h):(u=e*Math.pow(2,h-1)*Math.pow(2,i),s=0));i>=8;t[n+p]=255&u,p+=d,u/=256,i-=8);for(s=s<0;t[n+p]=255&s,p+=d,s/=256,c-=8);t[n+p-d]|=128*E}},function(t,e){var n={}.toString;t.exports=Array.isArray||function(t){return"[object Array]"==n.call(t)}},function(t,e){},function(t,e,n){"use strict";const r=n(2),{browser:i}=n(5),o=i?window.WebSocket:n(20);t.exports=class extends r{constructor(t){super(),this.client=t,this.ws=null,this.tries=0}async connect(t,e=this.tries){if(this.connected)return;const n=6463+e%10;this.hostAndPort=`localhost:${n}`;const r=this.ws=new o(`ws://${this.hostAndPort}/?v=1&client_id=${this.client.clientId}&encoding=json`);r.onopen=this.onOpen.bind(this),r.onclose=r.onerror=this.onClose.bind(this),r.onmessage=this.onMessage.bind(this)}send(t){var e;this.ws&&this.ws.send((e=t,JSON.stringify(e)))}close(){this.ws&&this.ws.close()}ping(){}onMessage(t){var e;this.emit("message",(e=t.data,JSON.parse(e)))}onOpen(){this.emit("open")}onClose(t){try{this.ws.close()}catch(t){}const e=t.code>=4e3&&t.code<5e3;t.code&&!e||(console.log(t),this.emit("close",t)),e||setTimeout(()=>this.connect(void 0,1006===t.code?++this.tries:0),250)}}},function(t,e){}])})); \ No newline at end of file diff --git a/scripts/lobby.js b/scripts/lobby.js new file mode 100644 index 0000000..b2fda06 --- /dev/null +++ b/scripts/lobby.js @@ -0,0 +1,200 @@ +// Lobby manages the players and games provided by the server and allows users to join or create their own games. +function Lobby(el){ + this.root = el; + + this.elements = { + status: this.root.getElementsByClassName("status")[0], + addr: this.root.getElementsByClassName("addr")[0], + games: this.root.getElementsByClassName("games")[0], + + stats: { + game: document.getElementById("game"), + packs: document.getElementById("packs"), + online: document.getElementById("online"), + ingame: document.getElementById("ingame"), + pubgame: document.getElementById("pubgame") + }, + + settings: { + name: document.getElementById("name"), + color: document.getElementById("usercolor") + } + }; + + this.top = new TopBar(document.getElementsByClassName("topbar")[0]); + + this.init = false; + this.online = []; + this.games = []; + this.packs = []; + this.players = []; +} + +Lobby.prototype = { + // Set initial pack list + // {data array} array of strings representing pack names + packList: function(data) { + this.packs = data; + this.top.setPacks(this.packs) + this.elements.stats.packs.innerText = this.packs.length(); + }, + + // Set initial game list. + // { data object } object containing {games} and {name} + // { data.name string } name of the game the server runs + // { data.games array } array of public games the server is running + // { data.games[n].name } room name + // { data.games[n].packs } list of the pack names used by this game + // { data.games[n].id } room identifier (uuid) + gameList: function(data) { + while (this.elements.games.firstChild != null) { + this.elements.games.remove(this.elements.games.firstChild) + } + + for (let i in data.games) { + let gel = new GameEl(i.name, i.packs, i.id); + this.games.push(gel); + this.elements.games.appendChild(gel.getElement()); + } + + this.elements.stats.game.innerText = data.name; + this.elements.stats.pubgame.innerText = this.games.length(); + }, + + // Set the initial player list. + // { data array } represents a list of player objects from the server + // { data[n].name string } name of the player + // { data[n].game string } id of the game room (empty if not in game). + // { data[n].color string } css color chosen by player. + // { data[n].uuid string } uuid of the player + players: function(data) { + + this.elements.stats.online.innerText = this.players.length(); + this.init = true; + }, + + // Called when a new public game is created on the server + // { data object } the game object + // { data.name } room name + // { data.packs } list of the pack names used by this game + // { data.id } room identifier (uuid) + addGame: function(data) { + + }, + + // Called when a new public game is removed on the server + // { data string } the uuid of the game to delete + removeGame: function(data) { + + }, + + // Called when a new player enters the lobby. + // { data object } an object representing the player + // { data.name string } name of the player + // { data.game string } id of the game room (empty if not in game). + // { data.color string } css color chosen by player. + // { data.uuid string } uuid of the player + addPlayer: function(data) { + + }, + + // Called when a player modifies their settings in the lobby. + // { data object } new player settings + // { data.name string } non null if the player has changed their name + // { data.color string } non null if the player has changed their color + // { data.uuid string } uuid of player changing their settings + modPlayer: function(data) { + + }, + + // Called when a player moves between the lobby and a game, or between two games + // { data object } new location + // { data.player } uuid of player changing location + // { data.loc } uuid of room player is moving to (empty if moving to lobby) + movePlayer: function(data) { + + }, + + // Called when a player exits the game (from lobby or game) + // {data string } uuid of player + removePlayer: function(data) { + + }, + + // Called when the client wants to toggle the new game screen + newGame: function() { + //if(this.init) return; + this.top.toggleNewGame(); + }, + + // Called when the client wants to toggle the mobile settings screen + mobileSettings: function() { + //if(this.init) return; + this.top.toggleMobileSettings(); + }, + + // Called when the WebSocket state has changed. + setState: function(text, color, server) { + this.elements.status.style.backgroundColor = color; + this.elements.status.innerText = text; + this.elements.addr.innerText = server; + this.top.setColor(color); + }, + + // Called when we are resetting the game. + reset: function() { + while (this.elements.games.firstChild != null) { + this.elements.games.remove(this.elements.games.firstChild) + } + + this.setState("Connecting", "#DA0", this.elements.addr.innerText); + this.init = false; + } +}; + +// ############### +// # TopBar Code # +// ############### + +// TopBar represents the bar at the top of the screen when client is in the lobby. + +function TopBar(el) { + this.root = el; + + this.newGame = el.getElementsByClassName("new-game")[0]; + this.mobileSettings = el.getElementsByClassName("mobile-settings")[0]; + this.status = el.getElementsByClassName("status")[0]; +} + +TopBar.prototype = { + // Set color of status bar + setColor: function(color) { + this.status.style.backgroundColor = color; + }, + + // Toggle showing the new game screen + toggleNewGame: function() { + if (this.newGame.style.display !== "none") + this.newGame.style.display = "none"; + else + this.newGame.style.display = "block"; + }, + + // Toggle showing the mobile settings + toggleMobileSettings: function() { + if (this.mobileSettings.style.display !== "none") + this.mobileSettings.style.display = "none"; + else + this.mobileSettings.style.display = "block"; + } +}; + +// ############# +// # Game code # +// ############# + +// GameEl represents a single game in the lobby view. It has methods for setting up the elements and such. + +function GameEl(name, packs, id) { + +} \ No newline at end of file diff --git a/scripts/message.js b/scripts/message.js new file mode 100644 index 0000000..5e821c4 --- /dev/null +++ b/scripts/message.js @@ -0,0 +1,14 @@ +function Message(type, data){ + this.t = type; + this.d = data; +} + +Message.prototype = { + stringify: function(){ + var dat = this.d + if(typeof dat !== "string"){ + dat = JSON.stringify(dat); + } + return JSON.stringify({type: this.t, data: dat}); + } +}; diff --git a/scripts/sock.js b/scripts/sock.js new file mode 100644 index 0000000..78c4195 --- /dev/null +++ b/scripts/sock.js @@ -0,0 +1,52 @@ +function SockWorker(serveraddr, version, callback) { + this.server = serveraddr; + this.version = version; + this.cb = callback; +} + +SockWorker.prototype = { + init: function() { + if(this.server == "" || this.server == null) { + return; + } + try { + this.socket = new WebSocket(this.server); + + this.socket.addEventListener("open", this.o.bind(this)); + this.socket.addEventListener("message", this.msg.bind(this)); + + this.socket.addEventListener("closed", this.c.bind(this)); + this.socket.addEventListener("error", this.err.bind(this)); + } catch (e) { + this.err(); + } + }, + + o: function() { + this.send("version", this.version); + }, + + msg: function(e) { + if(typeof e.data == "string") { + var dat = JSON.parse(e.data) + this.cb(dat); + } + }, + + c: function() { + this.cb({type: "close", data: ""}); + }, + + err: function() { + this.cb({type: "error", data: ""}); + }, + + close: function() { + this.socket.close(); + }, + + send: function(type, data) { + var m = new Message(type, data); + this.socket.send(m.stringify()) + } +}; \ No newline at end of file diff --git a/scripts/table.js b/scripts/table.js new file mode 100644 index 0000000..911763a --- /dev/null +++ b/scripts/table.js @@ -0,0 +1,16 @@ +// Table represents and manages the actual game. It accepts inputs from the server and tries to queries the server when the player makes a move. +function Table(el, soc) { + this.root = el; + this.soc = soc; +} + +Table.prototype = { + + handleClose: function() { + + }, + + reset: function() { + + } +} \ No newline at end of file diff --git a/styles/client/mobile.css b/styles/client/mobile.css index cea233d..4659ce6 100644 --- a/styles/client/mobile.css +++ b/styles/client/mobile.css @@ -1,4 +1,4 @@ -@media (max-width: 599px), (max-height: 500px) { +@media (max-width: 599px) or (max-height: 500px) { /* Hide stuff */ -- cgit v1.2.3