Repository: Nelderson/MV_Online
Branch: master
Commit: 5b879b38e4d6
Files: 41
Total size: 186.8 KB
Directory structure:
gitextract_htn83e9x/
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── Procfile
├── README.md
├── READMEs/
│ ├── Chat.md
│ ├── CloudSave.md
│ ├── Cors.md
│ ├── GlobalVariables.md
│ ├── Metrics.md
│ └── NetPlayers.md
├── api_routes/
│ ├── LoginSchema/
│ │ └── Account.js
│ ├── cloudsave.js
│ ├── cors.js
│ ├── example.js
│ ├── loginDBConnection.js
│ ├── login_routes.js
│ └── metrics.js
├── app.json
├── auth.js
├── configurations/
│ ├── chat.js
│ ├── config.js
│ └── cors.js
├── game_resources/
│ ├── css/
│ │ └── MMO.css
│ ├── js/
│ │ ├── libs/
│ │ │ ├── crypto.sha1.js
│ │ │ └── socket.io-2.2.0.js
│ │ └── plugins/
│ │ ├── Nasty_Text_Pop_Events.js
│ │ ├── Online_Chat.js
│ │ ├── Online_CloudSave.js
│ │ ├── Online_GlobalVars.js
│ │ ├── Online_Login_Core.js
│ │ ├── Online_Main_Core.js
│ │ ├── Online_Metrics.js
│ │ └── Online_Network_Players.js
│ └── sampleindex.html
├── package.json
├── server.js
└── socket_modules/
├── chat.js
├── exampleSocket.js
├── globalvar.js
└── netplayer.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
#MacOSX Stuffs
.DS_Store
.DS_Store?
#public folder
public
#Configuration Folder
server/configurations/config.js
# Logs
logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules
jspm_packages
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
================================================
FILE: CHANGELOG.md
================================================
# MV Online Version 0.2.0 Release Notes:
## Summary
There are 2 main points that are different from 0.1.0
- package.json has been updated with new versions of all the project's dependencies. To update all dependencies simply run the install command again after updating the server:
```bash
npm install
```
- With these newer packages the default method for registration and login have been changed. Registration and login by default now use sha256 encryption. This will not allow you to use the database already there unless you decide not to update your package.json and stick with previous versions.
## IMPORTANT!!!! YOU MUST CLEAR YOUR DATABASE AND START OVER OR FOLLOW THE INSTRUCTIONS BELOW:
- Keep the original package.json in your project or change the `passport-local-mongoose` entry to `^1.0.0"` as this will keep the original sha1 encryption.
- You'll also need to change line 103 to:
```js
crypto.pbkdf2(req.body.password, account.salt, 25000, 512, 'sha1', function(err, hashRaw){
```
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2017 Matthew Cipriano (Nelderson)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: Procfile
================================================
web: node server.js
================================================
FILE: README.md
================================================
MV Online Core Documentation
==========================
Requirements
-------------
Node.js and RPGMaker MV
Installation
-------------
Deploy to Heroku here:
[](https://dashboard.heroku.com/new?template=https://github.com/Nelderson/MV_Online/tree/master)
Use `git clone` or download and unzip to the directory of your choice.
Run `npm install` to download all dependencies for the server. Use `npm install -d` for windows users
After configuring the server run `npm start` to start the server
Server Configuration
-------------
Inside the `server/configurations/config.js` file, there are several things to configure:
`port` defines which port the server will run on (Default `8000`)
`jwtSecret` defines the secret the JWT is signed. Please change this for security reasons in a production environment
`firstHash` is the initial hashing secret for login system. This is the same as the client plugin first hash. Recommended that this be changed before putting in a production environment
`mailFrom` when a user registers they recieve an email from this address.
`smtps://username@gmail.com:password@smtp.gmail.com` (Additional steps are required if you want to use gmail.)
`mongoDBconnect` Link and credentials to MongoDB Database. `mongodb://username:password@linktomongodb.com:39504/collection`
Client Configuration (RPGMaker MV)
-------------
Add the `css` folder to the root of your project directory
Add the files in `game_resources/js/plugns` that you want for your plugins to your own `js/plugins` folder of your game. (`Online_Main_Core.js` is manditory for all other plugins)
Add the files from the `game_resources/js/libs` folder to your own `js/libs` folder
Modify your `index.html` file in your game to add this in the header:
```html
<!-- Nel Add -->
<link rel="stylesheet" type="text/css" href="./css/bootstrap3.3.5.min.css" >
<link rel="stylesheet" type="text/css" href="./css/fontawesome4.4.0.min.css" >
<link rel="stylesheet" type="text/css" href="./css/MMO.css">
<!-- Nel Add -->
```
And this in the body, dont forget the change localhost for your IP or Domain :
```html
<!-- Nel Add -->
<script type="text/javascript" src="./js/libs/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="./js/libs/jquerymobile1.4.5.min.js"></script>
<link rel="stylesheet" type="text/css" href="./css/jquerymobile1.4.5.min.css">
<script type="text/javascript" src="./js/libs/crypto.sha1.js"></script>
<script type="text/javascript" src="./js/libs/socket.io-2.2.0.js"></script>
<!-- Nel Add -->
```
================================================
FILE: READMEs/Chat.md
================================================
MV Online Chat Documentation
==========================
Introduction
-------------
The Online Chat Socket Module allows you to communicate with other players in your game using an in game chat window.
Installation
-------------
Make sure you have the `chat.js` file in your `socket_modules` folder.
Add this line to the `ADD SOCKET IO MODULES HERE` section in the `server.js` file:
`var chat = require('./socket_modules/chat');`
Add this line to the `BIND SOCKET IO MODULES HERE` section in the `server.js` file:
`chat(io);`
================================================
FILE: READMEs/CloudSave.md
================================================
MV Cloud Save Documentation
==========================
Introduction
-------------
`Cloud Save` allows you to store game data that you can use to project and show trends within your game
Configuration
-------------
Add this line to the `Authentication required` section in the `server.js` file:
`app.use('/cloudsave',require('./api_routes/cloudsave.js'));`
================================================
FILE: READMEs/Cors.md
================================================
MV Cors Documentation
==========================
Introduction
-------------
`api_routes/Cors.js` allows you to your server cors cross domain
`configurations/Cors.js` Configuration your cors domain
Configuration
-------------
Add this line to the `API SECTION` section in the `server.js` file:
`app.use('AllowCrossDomain',require('./api_routes/cors'));`
================================================
FILE: READMEs/GlobalVariables.md
================================================
MV Online Global Variables Documentation
==========================
Introduction
-------------
The Online Global Variables Socket Module allows you to send Variable and Switch data to other players connected.
Installation
-------------
Make sure you have the `globalvar.js` file in your `socket_modules` folder.
Add this line to the `ADD SOCKET IO MODULES HERE` section in the `server.js` file:
`var globalvar = require('./socket_modules/globalvar');`
Add this line to the `BIND SOCKET IO MODULES HERE` section in the `server.js` file:
`globalvar(io);`
================================================
FILE: READMEs/Metrics.md
================================================
MV Online Metrics Documentation
==========================
Introduction
-------------
`Metrics` allows you to store game data that you can use to project
and show trends within your game
Configuration
-------------
Add this line to the `Authentication required` section in the `server.js` file:
`app.use('/metrics',require('./api_routes/metrics'));`
The `metrics.js ` has only one configuration in the file for an anonymous flag.
This flag determines if you want the metrics to be anonymous, or the player has
to be signed into an account.
================================================
FILE: READMEs/NetPlayers.md
================================================
MV Net Players Documentation
==========================
Introduction
-------------
The Online Net Players Socket Module allows you to see other players on the same map
Installation
-------------
Make sure you have the `netplayer.js` file in your `socket_modules` folder.
Add this line to the `ADD SOCKET IO MODULES HERE` section in the `server.js` file:
`var netplayers = require('./socket_modules/netplayer');`
Add this line to the `BIND SOCKET IO MODULES HERE` section in the `server.js` file:
`netplayers(io);`
================================================
FILE: api_routes/LoginSchema/Account.js
================================================
//Version 0.1.0 - Added fields for password reset logic
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var passportLocalMongoose = require('passport-local-mongoose');
var allFields = 'id salt hash username email activated actCode rank socketId lostPasswordFlag lostPasswordTemp lostPasswordExpires';
var Account = new Schema({
username: {type: String, required: true, index: { unique: true}},
email: {type: String, required: true, index: { unique: true}},
activated: Boolean,
actCode: String,
socketId: String, //Current assigned socket
lostPasswordFlag: Boolean,
lostPasswordTemp: String,
lostPasswordExpires: Date,
rank: Number //0 - player, 1 - moderator, 2 - admin
});
Account.statics.findByName = function(name, cb) {
return this.findOne({ username: name}, allFields, cb);
};
Account.statics.findByEmail = function(email, cb) {
return this.findOne({ email: email}, allFields, cb);
};
Account.statics.activate = function(actCode, cb) {
return this.findOneAndUpdate({ 'actCode': actCode }, { activated: true }, cb);
};
Account.plugin(passportLocalMongoose, {
usernameQueryFields: ['username']
});
module.exports = mongoose.model('Account', Account);
================================================
FILE: api_routes/cloudsave.js
================================================
var mongoose = require("mongoose");
var express = require('express');
var authAPI = require('../auth.js').authAPI;
var router = express.Router();
var config = require('../configurations/config');
var log = require('tracer').colorConsole(config.loggingConfig);
var Save = new mongoose.Schema({
username: {type: String, required: true, index: { unique: true}},
email: {type: String, required: true, index: { unique: true}},
savedata: {type: String, required: true},
globaldata: {type: String, required: false}
});
var Saves = mongoose.model('Saves', Save);
//Need to have a valid token for all routes
router.use(authAPI);
router.get('/loadfromcloud', function(req, res){
var name = req.decoded.name;
Saves.findOne({username: name}, function(err,account){
if (err) log.error(err);
if (account){
return res.status(200).send(account.savedata);
}else{
return res.status(200).send("No account");
}
});
});
router.post('/savetocloud', function(req, res){
//Save to the database....
var name = req.decoded.name;
var email = req.decoded.email;
var savedata = req.body.savedata;
Saves.findOne({username: name}, function(err,account){
if (err) log.error(err);
if (account){
//Update save data to database
Saves.findOneAndUpdate({username: name}, {$set: {savedata:savedata}},function(err,data1){
if (err) log.error(err);
return res.status(200).send();
});
}else{
//Make New Account with save data
var newUser = new Saves({
username: name,
email: email,
savedata: savedata,
});
newUser.save(function(err,data){
if (err) log.error(err);
return res.status(200).send();
});
}
});
});
module.exports = router;
================================================
FILE: api_routes/cors.js
================================================
//----------------------------------
// Require file & Router :
//----------------------------------
var config = require('./../configurations/cors');
var server = require('../server');
var express = require('express');
var router = express.Router();
//----------------------------------
// Var Config :
//----------------------------------
var MyCorsHost = 'OriginDomain'
var MyMethods = 'MethodsCors'
var MyHeader = 'HeaderCors'
var AllowCrossDomain = 'CrossDomain'
//----------------------------------
// Allow Cors Domain:
//----------------------------------
var CrossDomain = function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'OriginDomain');
res.header('Access-Control-Allow-Methods', 'MethodsCors');
res.header('Access-Control-Allow-Headers', 'HeaderCors');
if (req.method === "OPTIONS")
res.send(200);
else
next();
}
module.exports = router;
================================================
FILE: api_routes/example.js
================================================
var express = require('express');
var authAPI = require('../auth.js').authAPI;
var router = express.Router();
//Need to have a valid token for all routes
router.use(authAPI);
router.get('/testing',function(req,res){
res.status(200).send('Dude....this is totally awesome');
});
module.exports = router;
================================================
FILE: api_routes/loginDBConnection.js
================================================
module.exports = function(){
var config = require('../configurations/config');
var mongoose = require('mongoose');
var log = require('tracer').colorConsole(config.loggingConfig);
//Mongo DB Database Connection
mongoose.connect(config.mongoDBconnect, { useNewUrlParser: true, useCreateIndex: true }, function(err) {
if (err) {
log.error(err);
}
});
};
================================================
FILE: api_routes/login_routes.js
================================================
var crypto = require('crypto');
var express = require('express');
var config = require('../configurations/config');
var log = require('tracer').colorConsole(config.loggingConfig);
var nodemailer = require('nodemailer');
var transporter = nodemailer.createTransport(config.mailFrom);
var Account = require('./LoginSchema/Account');
var jwt = require('jsonwebtoken');
var router = express.Router();
var authAPI = require('../auth.js').authAPI;
var sgMail = null;
if (process.env.SENDGRID_API_KEY){
sgMail = require('@sendgrid/mail');
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
}
router.get('/', function (req, res) {
res.status(203).json({});
});
router.get('/verify-token', function (req, res, next) {
authAPI(req,res,next)
}, function (req, res, next) {
res.status(203).json({token: req.decoded});
});
router.get('/register', function(req, res) {
res.status(403).json({});
});
router.post('/register', function(req, res) {
//Check if email not already used
Account.findByEmail(req.body.email, function(err, account){
if (err) {
return res.status(203).json({
pageData: {
err : err.message
}
});
}
if (account)
return res.status(203).json({
pageData: {
err : "Email '"+account.email+"' already registered"
}
});
//Create hash for activation code
var shasum = crypto.createHash('sha1');
shasum.update(req.body.username+req.body.email);
actCode = shasum.digest('hex');
//Hash the password a first time in sha1
var shapwd = crypto.createHash('sha1').update(req.body.password + config.firstHash).digest('hex');
Account.register(new Account({
username : req.body.username,
email : req.body.email,
activated : false,
actCode: actCode,
socketId: null,
rank: 0
}), shapwd, function(err, account) {
if (err) {
return res.status(203).json({
pageData: {
err : err.message
}
});
}
actUrl = `http://${req.headers.host}/activate/${actCode}`;
const messageBody = {
from: 'Team <no-reply@myserver.com>',
to: req.body.email,
subject: "RPGMaker MV MMO",
text: "Hello "+req.body.username+' and welcome to RPGMaker MV MMO!\nYour account has been registrated, but you need to activate it by following this link :\n'+actUrl+'\n\nEnjoy!\n\t-- Nelderson'
}
if (sgMail){
sgMail.send(messageBody)
.then(()=>{
log.info('Yes?');
return res.status(200).json({
pageData: {
msg : 'An activation link has been send to your email address.'
}
});
})
.catch(error => {
log.error(err);
return res.status(203).json({
pageData: {
err : 'Error sending email'
}
});
})
}
else{
transporter.sendMail({
...messageBody
},function(err,info){
if (err){
log.error(err);
return res.status(203).json({
pageData: {
err : 'Error sending email'
}
});
}else{
log.info(info);
return res.status(200).json({
pageData: {
msg : 'An activation link has been send to your email address.'
}
});
}
});
}
});
});
});
router.get('/login', function(req, res) {
res.status(203).json({});
});
router.post('/login', function(req, res){
Account.findByName(req.body.username, function(err, account){
if (err) {
return res.status(203).json({
err: err.msg
});
}
if (!account) {
return res.status(203).json({
err: "Invalid username"
});
}
var profile = {
name: account.username,
email: account.email,
id: account._id,
rank: account.rank
};
//Check for lost password flag and temp password
if (account.lostPasswordFlag===true){
var tempPasswordHash = crypto.createHash('sha1').update(account.lostPasswordTemp + config.firstHash).digest('hex');
if (tempPasswordHash===req.body.password){
//Check lostPasswordExpires
if (Date.now() > account.lostPasswordExpires){
return res.status(203).json({
err: "Temporary Password is Expired!"
});
}
return res.status(200).json({
temp:tempPasswordHash,
name:account.username
});
}
}
//Check for normal password
crypto.pbkdf2(req.body.password, account.salt, 25000, 512, 'sha256', function(err, hashRaw){
var hpass = new Buffer(hashRaw, 'binary').toString('hex');
if (account.hash == hpass) {
if (!account.activated){
return res.status(203).json({
err: "Account Not Activated"
});
}
var token = jwt.sign(profile, config.jwtSecret, { expiresIn: 60*config.tokenExpiresIn});
return res.status(200).json({token: token});
}
return res.status(203).json({
err: "Invalid password"
});
});
});
});
router.get('/activate/:actCode', function(req, res) {
var actCode = req.params.actCode;
Account.activate(actCode, function(err, account){
if (err) {
return res.status(203).json('activation', {
pageData: {
err: err.message
}
});
}
if (!account) {
return res.status(203).json('activation', {
pageData: {
err: "Can't activate account : Unknown token '<b>"+actCode+"</b>'."
}
});
}
return res.status(200).json('activation');
});
});
router.post('/lostpassword', function(req, res){
var randomPass=crypto.randomBytes(config.lostPasswordComplexity).toString('hex');
Account.findOneAndUpdate({email:req.body.email},
{lostPasswordFlag:true,lostPasswordTemp:randomPass,lostPasswordExpires:Date.now() + config.tempPasswordExpires},
function(err, account){
if (!account.activated){
return res.status(203).json({
err: "Account Not Activated"
});
}
if (err) {
return res.status(203).json({
err: err.msg
});
}
if (!account) {
return res.status(203).json({
err: "Email not found"
});
}
// Send Email with random temporary password
transporter.sendMail({
from: 'Team <no-reply@myserver.com>',
to: account.email,
subject: "RPGMaker MV MMO",
text: "Hello "+account.username+' \nyour temporary account password is: '+randomPass,
html: "Hello "+account.username+' \nyour temporary account password is: '+randomPass,
},function(err,info){
if (err){
log.error(err);
}else{
log.info(info);
}
});
return res.status(200).json({});
});
});
router.post('/resetpassword', function(req, res){
Account.findByName(req.body.tempName, function(err,account){
if (err){
return res.status(203).json({
err: err.msg
});
}
if (!account) {
return res.status(203).json({
err: "Error Occured (Account Not Found)"
});
}
if (!account.lostPasswordFlag){
return res.status(203).json({
err: "Please go through the password reset process the normal way...."
});
}
var tempPasswordHash = crypto.createHash('sha1').update(account.lostPasswordTemp + config.firstHash).digest('hex');
if (req.body.tempHash!==tempPasswordHash){
return res.status(203).json({
err: "Please go through the password reset process the normal way...."
});
}
if (Date.now() > account.lostPasswordExpires){
return res.status(203).json({
err: "Temporary Password is Expired!"
});
}
account.setPassword(req.body.password, function(err,data){
if (err){
return res.status(203).json({
err: err.message
});
}
if (data){
account.lostPasswordFlag = false;
account.save().then(function(error,data){
if (err) log.error(err);
return res.status(200).json({});
});
}
});
});
});
module.exports = router;
================================================
FILE: api_routes/metrics.js
================================================
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var express = require('express');
var authAPI = require('../auth.js').authAPI;
var router = express.Router();
var config = require('../configurations/config');
var log = require('tracer').colorConsole(config.loggingConfig);
//============Config Section=============//
//Set this the same as client anonymous flag
var anonymous = process.env.MV_METRICS_ANONYMOUS || false;
//======================================//
if (!anonymous){
var Metric = new Schema({
username: {type: String, required: true, index: { unique: true}},
email: {type: String, required: true, index: { unique: true}},
data: [{body: [], date: Date }],
});
}else{
var Metric = new Schema({
data: [{body: [], date: Date }],
});
}
var Metrics = mongoose.model('Metrics', Metric);
if (!anonymous){
//Need to have a valid token for all routes
router.use(authAPI);
}
router.post('/datadump', function(req, res) {
var name, email, id;
if (!anonymous){
id = req.body.id;
name = req.decoded.name;
email = req.decoded.email;
}
var data = {
body: [req.body],
date: Date.now()
};
if (!anonymous){
Metrics.findOne({username: name}, 'username', function(err,account){
if (account){
//Metrics collection started
Metrics.findOneAndUpdate({username: name}, {$push: {data:data}},function(err,data1){
if (err) log.error(err);
return res.status(200).send('Done');
});
}else{
//Metrics collection NOT started
var newUser = new Metrics({
username: name,
email: email,
data: [data]
});
newUser.save(function(err,data){
if (err) log.error(err);
return res.status(200).send('Done');
});
}
});
}else{
//Anonymous Metrics
Metrics.findOne({_id: id}, function(err,account){
if (account){
//Metrics collection started
Metrics.findOneAndUpdate({_id: id}, {$push: {data:data}},function(err,data1){
if (err) log.error(err);
return res.status(200).send(id);
});
}else{
//Metrics collection NOT started
var newUser = new Metrics({
username: 'null',
email: 'null',
data: [data]
});
newUser.save(function(err,data){
var uid = newUser._id;
if (err) log.error(err);
return res.status(200).send(uid);
});
}
});
}
});
module.exports = router;
================================================
FILE: app.json
================================================
{
"name": "MV Online",
"description": "MV Online system created by Nelderson",
"repository": "https://github.com/Nelderson/MV_Online",
"logo": "https://i.imgur.com/I0fAzpx.png",
"keywords": ["node", "express", "static"],
"env": {
"MV_JWT_SECRET": {
"description": "A secret key for verifying the integrity of signed JSON Web Tokens.",
"generator": "secret"
},
"MV_FIRST_HASH": {
"description": "The first hash to pass all passwords through",
"generator": "secret"
},
"MV_TOKEN_EXPIRES_MIN": {
"description": "The amount of minutes before token expires (20160 = 14 Days)",
"value": "20160"
},
"MV_WORKER_COUNT" :{
"description": "The amount of workers the cluster will use",
"value": "4"
},
"MV_ENFORCE_ONE_USER" :{
"description": "Allow only one login per user",
"value": "false"
},
"MV_LOST_PASSWORD_COMPLEXITY" :{
"description": "Complexity of lost password (Default 2)",
"value": "2"
},
"MV_LOST_PASSWORD_EXPIRES" :{
"description": "Temporary Password Expiration in Milliseconds (3600000 = 1hr)",
"value": "3600000"
},
"MV_CHAT_ENABLE_LOGGING" :{
"description": "Enable logging on all chat windows",
"value": "false"
},
"MV_CHAT_PROFANITY_FILTER" :{
"description": "Enable profanity filter on all chat windows",
"value": "false"
},
"MV_METRICS_ANONYMOUS" :{
"description": "Make metrics anonymous",
"value": "false"
}
},
"addons": [
{
"plan": "mongolab:sandbox",
"as": "MV_MONGO"
},
{
"plan": "heroku-redis:hobby-dev",
"as": "MV_REDIS_HOST"
},
{
"plan": "sendgrid:starter"
}
]
}
================================================
FILE: auth.js
================================================
var jwt = require('jsonwebtoken');
var config = require('./configurations/config');
var authAPI = function(req, res, next){
// check header or url parameters or post parameters for token
var token = req.body.token || req.param('token') || req.headers['x-access-token'];
// decode token
if (token) {
// verifies secret and checks exp
jwt.verify(token, config.jwtSecret, function(err, decoded) {
if (err) {
return res.status(403).json({ success: false, message: 'Failed to authenticate token.' });
} else {
// if everything is good, save to request for use in other routes
req.decoded = decoded;
next();
}
});
} else {
// if there is no token
// return an error
return res.status(403).send({
success: false,
message: 'Not Authenticated'
});
}
};
var authSocket = function(socket, next){
var { token } = socket.handshake.query;
// decode token
if (token) {
// verifies secret and checks exp
jwt.verify(token, config.jwtSecret, function(err, decoded) {
if (err) {
return next(err);
} else {
// set user to decoded token
// for use throughout app
socket.user = decoded;
next(null);
}
});
} else {
// if there is no token
// return an error
return next('Not Authenticated')
}
};
module.exports.authAPI = authAPI;
module.exports.authSocket = authSocket;
================================================
FILE: configurations/chat.js
================================================
var Config = module.exports = {
//---------------------
//Main Configurations
//---------------------
enableLogging: process.env.MV_CHAT_ENABLE_LOGGING || false,
profanityFilter: process.env.MV_CHAT_PROFANITY_FILTER || false,
};
================================================
FILE: configurations/config.js
================================================
var Config = module.exports = {
//---------------------
//Main Configurations
//---------------------
port: process.env.PORT || 8000,
jwtSecret: process.env.MV_JWT_SECRET || 'aeha8j4h20adn92k10nkav0sjf90sleicazvyi54j39jfqasfjk9',
loggingConfig: {
format : [
"{{timestamp}} <{{title}}> {{message}}", //default format
{
error : "{{timestamp}} <{{title}}> {{message}} (in {{file}}:{{line}})\nCall Stack:\n{{stack}}" // error format
}
],
dateformat : "HH:MM:ss.L",
preprocess : function(data){
data.title = data.title.toUpperCase();
},
level: 'debug'
},
redisConnection: process.env.MV_REDIS_HOST_URL || 'redis://localhost',
//---------------------
//Login Configurations
//---------------------
//Needs to be the same as Client firstHash
firstHash: process.env.MV_FIRST_HASH||'d28cb767c4272d8ab91000283c67747cb2ef7cd1',
//Mail to send activation codes from
mailFrom: process.env.MV_MAILFROM || 'smtps://username@gmail.com:password@smtp.gmail.com',
//Time until token expires (in minutes)
tokenExpiresIn: process.env.MV_TOKEN_EXPIRES_MIN || 60 * 24 * 14,
//Allows only one logged in user at a time.
enforceOneUser: process.env.MV_ENFORCE_ONE_USER || false,
//Temporary Password Complexity for lost Passwords
lostPasswordComplexity: process.env.MV_LOST_PASSWORD_COMPLEXITY || 2,
//Temporary Password Expiration in Milliseconds
tempPasswordExpires: process.env.MV_LOST_PASSWORD_EXPIRES || 3600000, //1 hour
//------------------------
//Database Configurations
//------------------------
mongoDBconnect: process.env.MV_MONGO_URI || 'mongodb://username:password@linktomongodb.com:39504/collection'
};
================================================
FILE: configurations/cors.js
================================================
var Config = module.exports = {
//---------------------
//Cors Configurations
//---------------------
MyCorsHost: '*',
MyMethods: 'GET,PUT,POST',
MyHeader: 'DNT,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range, X-Acces-Token, Accept-Type'
};
================================================
FILE: game_resources/css/MMO.css
================================================
/*
* @Author: Vinxce
* @Date: 2015-10-27 10:55:44
* @Last Modified by: Vinxce
* @Last Modified time: 2015-10-27 21:31:32
*/
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
#LoginForm {
margin: auto;
text-shadow: none !important;
position: relative;
bottom: 50px;
animation: fadeIn 1 ease-in;
}
#RegisterForm{
margin: auto;
text-shadow: none !important;
position: relative;
bottom: 50px;
animation: fadeIn 1 ease-in;
}
#ActivationForm{
margin: auto;
text-shadow: none !important;
position: relative;
bottom: 50px;
animation: fadeIn 1 ease-in;
}
================================================
FILE: game_resources/js/libs/crypto.sha1.js
================================================
/*
CryptoJS v3.1.2
code.google.com/p/crypto-js
(c) 2009-2013 by Jeff Mott. All rights reserved.
code.google.com/p/crypto-js/wiki/License
*/
var CryptoJS=CryptoJS||function(e,m){var p={},j=p.lib={},l=function(){},f=j.Base={extend:function(a){l.prototype=this;var c=new l;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}},
n=j.WordArray=f.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=m?c:4*a.length},toString:function(a){return(a||h).stringify(this)},concat:function(a){var c=this.words,q=a.words,d=this.sigBytes;a=a.sigBytes;this.clamp();if(d%4)for(var b=0;b<a;b++)c[d+b>>>2]|=(q[b>>>2]>>>24-8*(b%4)&255)<<24-8*((d+b)%4);else if(65535<q.length)for(b=0;b<a;b+=4)c[d+b>>>2]=q[b>>>2];else c.push.apply(c,q);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<<
32-8*(c%4);a.length=e.ceil(c/4)},clone:function(){var a=f.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],b=0;b<a;b+=4)c.push(4294967296*e.random()|0);return new n.init(c,a)}}),b=p.enc={},h=b.Hex={stringify:function(a){var c=a.words;a=a.sigBytes;for(var b=[],d=0;d<a;d++){var f=c[d>>>2]>>>24-8*(d%4)&255;b.push((f>>>4).toString(16));b.push((f&15).toString(16))}return b.join("")},parse:function(a){for(var c=a.length,b=[],d=0;d<c;d+=2)b[d>>>3]|=parseInt(a.substr(d,
2),16)<<24-4*(d%8);return new n.init(b,c/2)}},g=b.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var b=[],d=0;d<a;d++)b.push(String.fromCharCode(c[d>>>2]>>>24-8*(d%4)&255));return b.join("")},parse:function(a){for(var c=a.length,b=[],d=0;d<c;d++)b[d>>>2]|=(a.charCodeAt(d)&255)<<24-8*(d%4);return new n.init(b,c)}},r=b.Utf8={stringify:function(a){try{return decodeURIComponent(escape(g.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return g.parse(unescape(encodeURIComponent(a)))}},
k=j.BufferedBlockAlgorithm=f.extend({reset:function(){this._data=new n.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=r.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,b=c.words,d=c.sigBytes,f=this.blockSize,h=d/(4*f),h=a?e.ceil(h):e.max((h|0)-this._minBufferSize,0);a=h*f;d=e.min(4*a,d);if(a){for(var g=0;g<a;g+=f)this._doProcessBlock(b,g);g=b.splice(0,a);c.sigBytes-=d}return new n.init(g,d)},clone:function(){var a=f.clone.call(this);
a._data=this._data.clone();return a},_minBufferSize:0});j.Hasher=k.extend({cfg:f.extend(),init:function(a){this.cfg=this.cfg.extend(a);this.reset()},reset:function(){k.reset.call(this);this._doReset()},update:function(a){this._append(a);this._process();return this},finalize:function(a){a&&this._append(a);return this._doFinalize()},blockSize:16,_createHelper:function(a){return function(c,b){return(new a.init(b)).finalize(c)}},_createHmacHelper:function(a){return function(b,f){return(new s.HMAC.init(a,
f)).finalize(b)}}});var s=p.algo={};return p}(Math);
(function(){var e=CryptoJS,m=e.lib,p=m.WordArray,j=m.Hasher,l=[],m=e.algo.SHA1=j.extend({_doReset:function(){this._hash=new p.init([1732584193,4023233417,2562383102,271733878,3285377520])},_doProcessBlock:function(f,n){for(var b=this._hash.words,h=b[0],g=b[1],e=b[2],k=b[3],j=b[4],a=0;80>a;a++){if(16>a)l[a]=f[n+a]|0;else{var c=l[a-3]^l[a-8]^l[a-14]^l[a-16];l[a]=c<<1|c>>>31}c=(h<<5|h>>>27)+j+l[a];c=20>a?c+((g&e|~g&k)+1518500249):40>a?c+((g^e^k)+1859775393):60>a?c+((g&e|g&k|e&k)-1894007588):c+((g^e^
k)-899497514);j=k;k=e;e=g<<30|g>>>2;g=h;h=c}b[0]=b[0]+h|0;b[1]=b[1]+g|0;b[2]=b[2]+e|0;b[3]=b[3]+k|0;b[4]=b[4]+j|0},_doFinalize:function(){var f=this._data,e=f.words,b=8*this._nDataBytes,h=8*f.sigBytes;e[h>>>5]|=128<<24-h%32;e[(h+64>>>9<<4)+14]=Math.floor(b/4294967296);e[(h+64>>>9<<4)+15]=b;f.sigBytes=4*e.length;this._process();return this._hash},clone:function(){var e=j.clone.call(this);e._hash=this._hash.clone();return e}});e.SHA1=j._createHelper(m);e.HmacSHA1=j._createHmacHelper(m)})();
================================================
FILE: game_resources/js/libs/socket.io-2.2.0.js
================================================
/*!
* Socket.IO v2.2.0
* (c) 2014-2018 Guillermo Rauch
* Released under the MIT License.
*/
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.io=e():t.io=e()}(this,function(){return function(t){function e(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return t[r].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var n={};return e.m=t,e.c=n,e.p="",e(0)}([function(t,e,n){"use strict";function r(t,e){"object"===("undefined"==typeof t?"undefined":o(t))&&(e=t,t=void 0),e=e||{};var n,r=i(t),s=r.source,u=r.id,h=r.path,f=p[u]&&h in p[u].nsps,l=e.forceNew||e["force new connection"]||!1===e.multiplex||f;return l?(c("ignoring socket cache for %s",s),n=a(s,e)):(p[u]||(c("new io instance for %s",s),p[u]=a(s,e)),n=p[u]),r.query&&!e.query&&(e.query=r.query),n.socket(r.path,e)}var o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=n(1),s=n(7),a=n(12),c=n(3)("socket.io-client");t.exports=e=r;var p=e.managers={};e.protocol=s.protocol,e.connect=r,e.Manager=n(12),e.Socket=n(36)},function(t,e,n){"use strict";function r(t,e){var n=t;e=e||"undefined"!=typeof location&&location,null==t&&(t=e.protocol+"//"+e.host),"string"==typeof t&&("/"===t.charAt(0)&&(t="/"===t.charAt(1)?e.protocol+t:e.host+t),/^(https?|wss?):\/\//.test(t)||(i("protocol-less url %s",t),t="undefined"!=typeof e?e.protocol+"//"+t:"https://"+t),i("parse %s",t),n=o(t)),n.port||(/^(http|ws)$/.test(n.protocol)?n.port="80":/^(http|ws)s$/.test(n.protocol)&&(n.port="443")),n.path=n.path||"/";var r=n.host.indexOf(":")!==-1,s=r?"["+n.host+"]":n.host;return n.id=n.protocol+"://"+s+":"+n.port,n.href=n.protocol+"://"+s+(e&&e.port===n.port?"":":"+n.port),n}var o=n(2),i=n(3)("socket.io-client:url");t.exports=r},function(t,e){var n=/^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,r=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"];t.exports=function(t){var e=t,o=t.indexOf("["),i=t.indexOf("]");o!=-1&&i!=-1&&(t=t.substring(0,o)+t.substring(o,i).replace(/:/g,";")+t.substring(i,t.length));for(var s=n.exec(t||""),a={},c=14;c--;)a[r[c]]=s[c]||"";return o!=-1&&i!=-1&&(a.source=e,a.host=a.host.substring(1,a.host.length-1).replace(/;/g,":"),a.authority=a.authority.replace("[","").replace("]","").replace(/;/g,":"),a.ipv6uri=!0),a}},function(t,e,n){(function(r){function o(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type)||("undefined"==typeof navigator||!navigator.userAgent||!navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))&&("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))}function i(t){var n=this.useColors;if(t[0]=(n?"%c":"")+this.namespace+(n?" %c":" ")+t[0]+(n?"%c ":" ")+"+"+e.humanize(this.diff),n){var r="color: "+this.color;t.splice(1,0,r,"color: inherit");var o=0,i=0;t[0].replace(/%[a-zA-Z%]/g,function(t){"%%"!==t&&(o++,"%c"===t&&(i=o))}),t.splice(i,0,r)}}function s(){return"object"==typeof console&&console.log&&Function.prototype.apply.call(console.log,console,arguments)}function a(t){try{null==t?e.storage.removeItem("debug"):e.storage.debug=t}catch(n){}}function c(){var t;try{t=e.storage.debug}catch(n){}return!t&&"undefined"!=typeof r&&"env"in r&&(t=r.env.DEBUG),t}function p(){try{return window.localStorage}catch(t){}}e=t.exports=n(5),e.log=s,e.formatArgs=i,e.save=a,e.load=c,e.useColors=o,e.storage="undefined"!=typeof chrome&&"undefined"!=typeof chrome.storage?chrome.storage.local:p(),e.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],e.formatters.j=function(t){try{return JSON.stringify(t)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}},e.enable(c())}).call(e,n(4))},function(t,e){function n(){throw new Error("setTimeout has not been defined")}function r(){throw new Error("clearTimeout has not been defined")}function o(t){if(u===setTimeout)return setTimeout(t,0);if((u===n||!u)&&setTimeout)return u=setTimeout,setTimeout(t,0);try{return u(t,0)}catch(e){try{return u.call(null,t,0)}catch(e){return u.call(this,t,0)}}}function i(t){if(h===clearTimeout)return clearTimeout(t);if((h===r||!h)&&clearTimeout)return h=clearTimeout,clearTimeout(t);try{return h(t)}catch(e){try{return h.call(null,t)}catch(e){return h.call(this,t)}}}function s(){y&&l&&(y=!1,l.length?d=l.concat(d):m=-1,d.length&&a())}function a(){if(!y){var t=o(s);y=!0;for(var e=d.length;e;){for(l=d,d=[];++m<e;)l&&l[m].run();m=-1,e=d.length}l=null,y=!1,i(t)}}function c(t,e){this.fun=t,this.array=e}function p(){}var u,h,f=t.exports={};!function(){try{u="function"==typeof setTimeout?setTimeout:n}catch(t){u=n}try{h="function"==typeof clearTimeout?clearTimeout:r}catch(t){h=r}}();var l,d=[],y=!1,m=-1;f.nextTick=function(t){var e=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)e[n-1]=arguments[n];d.push(new c(t,e)),1!==d.length||y||o(a)},c.prototype.run=function(){this.fun.apply(null,this.array)},f.title="browser",f.browser=!0,f.env={},f.argv=[],f.version="",f.versions={},f.on=p,f.addListener=p,f.once=p,f.off=p,f.removeListener=p,f.removeAllListeners=p,f.emit=p,f.prependListener=p,f.prependOnceListener=p,f.listeners=function(t){return[]},f.binding=function(t){throw new Error("process.binding is not supported")},f.cwd=function(){return"/"},f.chdir=function(t){throw new Error("process.chdir is not supported")},f.umask=function(){return 0}},function(t,e,n){function r(t){var n,r=0;for(n in t)r=(r<<5)-r+t.charCodeAt(n),r|=0;return e.colors[Math.abs(r)%e.colors.length]}function o(t){function n(){if(n.enabled){var t=n,r=+new Date,i=r-(o||r);t.diff=i,t.prev=o,t.curr=r,o=r;for(var s=new Array(arguments.length),a=0;a<s.length;a++)s[a]=arguments[a];s[0]=e.coerce(s[0]),"string"!=typeof s[0]&&s.unshift("%O");var c=0;s[0]=s[0].replace(/%([a-zA-Z%])/g,function(n,r){if("%%"===n)return n;c++;var o=e.formatters[r];if("function"==typeof o){var i=s[c];n=o.call(t,i),s.splice(c,1),c--}return n}),e.formatArgs.call(t,s);var p=n.log||e.log||console.log.bind(console);p.apply(t,s)}}var o;return n.namespace=t,n.enabled=e.enabled(t),n.useColors=e.useColors(),n.color=r(t),n.destroy=i,"function"==typeof e.init&&e.init(n),e.instances.push(n),n}function i(){var t=e.instances.indexOf(this);return t!==-1&&(e.instances.splice(t,1),!0)}function s(t){e.save(t),e.names=[],e.skips=[];var n,r=("string"==typeof t?t:"").split(/[\s,]+/),o=r.length;for(n=0;n<o;n++)r[n]&&(t=r[n].replace(/\*/g,".*?"),"-"===t[0]?e.skips.push(new RegExp("^"+t.substr(1)+"$")):e.names.push(new RegExp("^"+t+"$")));for(n=0;n<e.instances.length;n++){var i=e.instances[n];i.enabled=e.enabled(i.namespace)}}function a(){e.enable("")}function c(t){if("*"===t[t.length-1])return!0;var n,r;for(n=0,r=e.skips.length;n<r;n++)if(e.skips[n].test(t))return!1;for(n=0,r=e.names.length;n<r;n++)if(e.names[n].test(t))return!0;return!1}function p(t){return t instanceof Error?t.stack||t.message:t}e=t.exports=o.debug=o["default"]=o,e.coerce=p,e.disable=a,e.enable=s,e.enabled=c,e.humanize=n(6),e.instances=[],e.names=[],e.skips=[],e.formatters={}},function(t,e){function n(t){if(t=String(t),!(t.length>100)){var e=/^((?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(t);if(e){var n=parseFloat(e[1]),r=(e[2]||"ms").toLowerCase();switch(r){case"years":case"year":case"yrs":case"yr":case"y":return n*u;case"days":case"day":case"d":return n*p;case"hours":case"hour":case"hrs":case"hr":case"h":return n*c;case"minutes":case"minute":case"mins":case"min":case"m":return n*a;case"seconds":case"second":case"secs":case"sec":case"s":return n*s;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return n;default:return}}}}function r(t){return t>=p?Math.round(t/p)+"d":t>=c?Math.round(t/c)+"h":t>=a?Math.round(t/a)+"m":t>=s?Math.round(t/s)+"s":t+"ms"}function o(t){return i(t,p,"day")||i(t,c,"hour")||i(t,a,"minute")||i(t,s,"second")||t+" ms"}function i(t,e,n){if(!(t<e))return t<1.5*e?Math.floor(t/e)+" "+n:Math.ceil(t/e)+" "+n+"s"}var s=1e3,a=60*s,c=60*a,p=24*c,u=365.25*p;t.exports=function(t,e){e=e||{};var i=typeof t;if("string"===i&&t.length>0)return n(t);if("number"===i&&isNaN(t)===!1)return e["long"]?o(t):r(t);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(t))}},function(t,e,n){function r(){}function o(t){var n=""+t.type;if(e.BINARY_EVENT!==t.type&&e.BINARY_ACK!==t.type||(n+=t.attachments+"-"),t.nsp&&"/"!==t.nsp&&(n+=t.nsp+","),null!=t.id&&(n+=t.id),null!=t.data){var r=i(t.data);if(r===!1)return g;n+=r}return f("encoded %j as %s",t,n),n}function i(t){try{return JSON.stringify(t)}catch(e){return!1}}function s(t,e){function n(t){var n=d.deconstructPacket(t),r=o(n.packet),i=n.buffers;i.unshift(r),e(i)}d.removeBlobs(t,n)}function a(){this.reconstructor=null}function c(t){var n=0,r={type:Number(t.charAt(0))};if(null==e.types[r.type])return h("unknown packet type "+r.type);if(e.BINARY_EVENT===r.type||e.BINARY_ACK===r.type){for(var o="";"-"!==t.charAt(++n)&&(o+=t.charAt(n),n!=t.length););if(o!=Number(o)||"-"!==t.charAt(n))throw new Error("Illegal attachments");r.attachments=Number(o)}if("/"===t.charAt(n+1))for(r.nsp="";++n;){var i=t.charAt(n);if(","===i)break;if(r.nsp+=i,n===t.length)break}else r.nsp="/";var s=t.charAt(n+1);if(""!==s&&Number(s)==s){for(r.id="";++n;){var i=t.charAt(n);if(null==i||Number(i)!=i){--n;break}if(r.id+=t.charAt(n),n===t.length)break}r.id=Number(r.id)}if(t.charAt(++n)){var a=p(t.substr(n)),c=a!==!1&&(r.type===e.ERROR||y(a));if(!c)return h("invalid payload");r.data=a}return f("decoded %s as %j",t,r),r}function p(t){try{return JSON.parse(t)}catch(e){return!1}}function u(t){this.reconPack=t,this.buffers=[]}function h(t){return{type:e.ERROR,data:"parser error: "+t}}var f=n(3)("socket.io-parser"),l=n(8),d=n(9),y=n(10),m=n(11);e.protocol=4,e.types=["CONNECT","DISCONNECT","EVENT","ACK","ERROR","BINARY_EVENT","BINARY_ACK"],e.CONNECT=0,e.DISCONNECT=1,e.EVENT=2,e.ACK=3,e.ERROR=4,e.BINARY_EVENT=5,e.BINARY_ACK=6,e.Encoder=r,e.Decoder=a;var g=e.ERROR+'"encode error"';r.prototype.encode=function(t,n){if(f("encoding packet %j",t),e.BINARY_EVENT===t.type||e.BINARY_ACK===t.type)s(t,n);else{var r=o(t);n([r])}},l(a.prototype),a.prototype.add=function(t){var n;if("string"==typeof t)n=c(t),e.BINARY_EVENT===n.type||e.BINARY_ACK===n.type?(this.reconstructor=new u(n),0===this.reconstructor.reconPack.attachments&&this.emit("decoded",n)):this.emit("decoded",n);else{if(!m(t)&&!t.base64)throw new Error("Unknown type: "+t);if(!this.reconstructor)throw new Error("got binary data when not reconstructing a packet");n=this.reconstructor.takeBinaryData(t),n&&(this.reconstructor=null,this.emit("decoded",n))}},a.prototype.destroy=function(){this.reconstructor&&this.reconstructor.finishedReconstruction()},u.prototype.takeBinaryData=function(t){if(this.buffers.push(t),this.buffers.length===this.reconPack.attachments){var e=d.reconstructPacket(this.reconPack,this.buffers);return this.finishedReconstruction(),e}return null},u.prototype.finishedReconstruction=function(){this.reconPack=null,this.buffers=[]}},function(t,e,n){function r(t){if(t)return o(t)}function o(t){for(var e in r.prototype)t[e]=r.prototype[e];return t}t.exports=r,r.prototype.on=r.prototype.addEventListener=function(t,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+t]=this._callbacks["$"+t]||[]).push(e),this},r.prototype.once=function(t,e){function n(){this.off(t,n),e.apply(this,arguments)}return n.fn=e,this.on(t,n),this},r.prototype.off=r.prototype.removeListener=r.prototype.removeAllListeners=r.prototype.removeEventListener=function(t,e){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var n=this._callbacks["$"+t];if(!n)return this;if(1==arguments.length)return delete this._callbacks["$"+t],this;for(var r,o=0;o<n.length;o++)if(r=n[o],r===e||r.fn===e){n.splice(o,1);break}return this},r.prototype.emit=function(t){this._callbacks=this._callbacks||{};var e=[].slice.call(arguments,1),n=this._callbacks["$"+t];if(n){n=n.slice(0);for(var r=0,o=n.length;r<o;++r)n[r].apply(this,e)}return this},r.prototype.listeners=function(t){return this._callbacks=this._callbacks||{},this._callbacks["$"+t]||[]},r.prototype.hasListeners=function(t){return!!this.listeners(t).length}},function(t,e,n){function r(t,e){if(!t)return t;if(s(t)){var n={_placeholder:!0,num:e.length};return e.push(t),n}if(i(t)){for(var o=new Array(t.length),a=0;a<t.length;a++)o[a]=r(t[a],e);return o}if("object"==typeof t&&!(t instanceof Date)){var o={};for(var c in t)o[c]=r(t[c],e);return o}return t}function o(t,e){if(!t)return t;if(t&&t._placeholder)return e[t.num];if(i(t))for(var n=0;n<t.length;n++)t[n]=o(t[n],e);else if("object"==typeof t)for(var r in t)t[r]=o(t[r],e);return t}var i=n(10),s=n(11),a=Object.prototype.toString,c="function"==typeof Blob||"undefined"!=typeof Blob&&"[object BlobConstructor]"===a.call(Blob),p="function"==typeof File||"undefined"!=typeof File&&"[object FileConstructor]"===a.call(File);e.deconstructPacket=function(t){var e=[],n=t.data,o=t;return o.data=r(n,e),o.attachments=e.length,{packet:o,buffers:e}},e.reconstructPacket=function(t,e){return t.data=o(t.data,e),t.attachments=void 0,t},e.removeBlobs=function(t,e){function n(t,a,u){if(!t)return t;if(c&&t instanceof Blob||p&&t instanceof File){r++;var h=new FileReader;h.onload=function(){u?u[a]=this.result:o=this.result,--r||e(o)},h.readAsArrayBuffer(t)}else if(i(t))for(var f=0;f<t.length;f++)n(t[f],f,t);else if("object"==typeof t&&!s(t))for(var l in t)n(t[l],l,t)}var r=0,o=t;n(o),r||e(o)}},function(t,e){var n={}.toString;t.exports=Array.isArray||function(t){return"[object Array]"==n.call(t)}},function(t,e){function n(t){return r&&Buffer.isBuffer(t)||o&&(t instanceof ArrayBuffer||i(t))}t.exports=n;var r="function"==typeof Buffer&&"function"==typeof Buffer.isBuffer,o="function"==typeof ArrayBuffer,i=function(t){return"function"==typeof ArrayBuffer.isView?ArrayBuffer.isView(t):t.buffer instanceof ArrayBuffer}},function(t,e,n){"use strict";function r(t,e){if(!(this instanceof r))return new r(t,e);t&&"object"===("undefined"==typeof t?"undefined":o(t))&&(e=t,t=void 0),e=e||{},e.path=e.path||"/socket.io",this.nsps={},this.subs=[],this.opts=e,this.reconnection(e.reconnection!==!1),this.reconnectionAttempts(e.reconnectionAttempts||1/0),this.reconnectionDelay(e.reconnectionDelay||1e3),this.reconnectionDelayMax(e.reconnectionDelayMax||5e3),this.randomizationFactor(e.randomizationFactor||.5),this.backoff=new l({min:this.reconnectionDelay(),max:this.reconnectionDelayMax(),jitter:this.randomizationFactor()}),this.timeout(null==e.timeout?2e4:e.timeout),this.readyState="closed",this.uri=t,this.connecting=[],this.lastPing=null,this.encoding=!1,this.packetBuffer=[];var n=e.parser||c;this.encoder=new n.Encoder,this.decoder=new n.Decoder,this.autoConnect=e.autoConnect!==!1,this.autoConnect&&this.open()}var o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=n(13),s=n(36),a=n(8),c=n(7),p=n(38),u=n(39),h=n(3)("socket.io-client:manager"),f=n(35),l=n(40),d=Object.prototype.hasOwnProperty;t.exports=r,r.prototype.emitAll=function(){this.emit.apply(this,arguments);for(var t in this.nsps)d.call(this.nsps,t)&&this.nsps[t].emit.apply(this.nsps[t],arguments)},r.prototype.updateSocketIds=function(){for(var t in this.nsps)d.call(this.nsps,t)&&(this.nsps[t].id=this.generateId(t))},r.prototype.generateId=function(t){return("/"===t?"":t+"#")+this.engine.id},a(r.prototype),r.prototype.reconnection=function(t){return arguments.length?(this._reconnection=!!t,this):this._reconnection},r.prototype.reconnectionAttempts=function(t){return arguments.length?(this._reconnectionAttempts=t,this):this._reconnectionAttempts},r.prototype.reconnectionDelay=function(t){return arguments.length?(this._reconnectionDelay=t,this.backoff&&this.backoff.setMin(t),this):this._reconnectionDelay},r.prototype.randomizationFactor=function(t){return arguments.length?(this._randomizationFactor=t,this.backoff&&this.backoff.setJitter(t),this):this._randomizationFactor},r.prototype.reconnectionDelayMax=function(t){return arguments.length?(this._reconnectionDelayMax=t,this.backoff&&this.backoff.setMax(t),this):this._reconnectionDelayMax},r.prototype.timeout=function(t){return arguments.length?(this._timeout=t,this):this._timeout},r.prototype.maybeReconnectOnOpen=function(){!this.reconnecting&&this._reconnection&&0===this.backoff.attempts&&this.reconnect()},r.prototype.open=r.prototype.connect=function(t,e){if(h("readyState %s",this.readyState),~this.readyState.indexOf("open"))return this;h("opening %s",this.uri),this.engine=i(this.uri,this.opts);var n=this.engine,r=this;this.readyState="opening",this.skipReconnect=!1;var o=p(n,"open",function(){r.onopen(),t&&t()}),s=p(n,"error",function(e){if(h("connect_error"),r.cleanup(),r.readyState="closed",r.emitAll("connect_error",e),t){var n=new Error("Connection error");n.data=e,t(n)}else r.maybeReconnectOnOpen()});if(!1!==this._timeout){var a=this._timeout;h("connect attempt will timeout after %d",a);var c=setTimeout(function(){h("connect attempt timed out after %d",a),o.destroy(),n.close(),n.emit("error","timeout"),r.emitAll("connect_timeout",a)},a);this.subs.push({destroy:function(){clearTimeout(c)}})}return this.subs.push(o),this.subs.push(s),this},r.prototype.onopen=function(){h("open"),this.cleanup(),this.readyState="open",this.emit("open");var t=this.engine;this.subs.push(p(t,"data",u(this,"ondata"))),this.subs.push(p(t,"ping",u(this,"onping"))),this.subs.push(p(t,"pong",u(this,"onpong"))),this.subs.push(p(t,"error",u(this,"onerror"))),this.subs.push(p(t,"close",u(this,"onclose"))),this.subs.push(p(this.decoder,"decoded",u(this,"ondecoded")))},r.prototype.onping=function(){this.lastPing=new Date,this.emitAll("ping")},r.prototype.onpong=function(){this.emitAll("pong",new Date-this.lastPing)},r.prototype.ondata=function(t){this.decoder.add(t)},r.prototype.ondecoded=function(t){this.emit("packet",t)},r.prototype.onerror=function(t){h("error",t),this.emitAll("error",t)},r.prototype.socket=function(t,e){function n(){~f(o.connecting,r)||o.connecting.push(r)}var r=this.nsps[t];if(!r){r=new s(this,t,e),this.nsps[t]=r;var o=this;r.on("connecting",n),r.on("connect",function(){r.id=o.generateId(t)}),this.autoConnect&&n()}return r},r.prototype.destroy=function(t){var e=f(this.connecting,t);~e&&this.connecting.splice(e,1),this.connecting.length||this.close()},r.prototype.packet=function(t){h("writing packet %j",t);var e=this;t.query&&0===t.type&&(t.nsp+="?"+t.query),e.encoding?e.packetBuffer.push(t):(e.encoding=!0,this.encoder.encode(t,function(n){for(var r=0;r<n.length;r++)e.engine.write(n[r],t.options);e.encoding=!1,e.processPacketQueue()}))},r.prototype.processPacketQueue=function(){if(this.packetBuffer.length>0&&!this.encoding){var t=this.packetBuffer.shift();this.packet(t)}},r.prototype.cleanup=function(){h("cleanup");for(var t=this.subs.length,e=0;e<t;e++){var n=this.subs.shift();n.destroy()}this.packetBuffer=[],this.encoding=!1,this.lastPing=null,this.decoder.destroy()},r.prototype.close=r.prototype.disconnect=function(){h("disconnect"),this.skipReconnect=!0,this.reconnecting=!1,"opening"===this.readyState&&this.cleanup(),this.backoff.reset(),this.readyState="closed",this.engine&&this.engine.close()},r.prototype.onclose=function(t){h("onclose"),this.cleanup(),this.backoff.reset(),this.readyState="closed",this.emit("close",t),this._reconnection&&!this.skipReconnect&&this.reconnect()},r.prototype.reconnect=function(){if(this.reconnecting||this.skipReconnect)return this;var t=this;if(this.backoff.attempts>=this._reconnectionAttempts)h("reconnect failed"),this.backoff.reset(),this.emitAll("reconnect_failed"),this.reconnecting=!1;else{var e=this.backoff.duration();h("will wait %dms before reconnect attempt",e),this.reconnecting=!0;var n=setTimeout(function(){t.skipReconnect||(h("attempting reconnect"),t.emitAll("reconnect_attempt",t.backoff.attempts),t.emitAll("reconnecting",t.backoff.attempts),t.skipReconnect||t.open(function(e){e?(h("reconnect attempt error"),t.reconnecting=!1,t.reconnect(),t.emitAll("reconnect_error",e.data)):(h("reconnect success"),t.onreconnect())}))},e);this.subs.push({destroy:function(){clearTimeout(n)}})}},r.prototype.onreconnect=function(){var t=this.backoff.attempts;this.reconnecting=!1,this.backoff.reset(),this.updateSocketIds(),this.emitAll("reconnect",t)}},function(t,e,n){t.exports=n(14),t.exports.parser=n(21)},function(t,e,n){function r(t,e){return this instanceof r?(e=e||{},t&&"object"==typeof t&&(e=t,t=null),t?(t=u(t),e.hostname=t.host,e.secure="https"===t.protocol||"wss"===t.protocol,e.port=t.port,t.query&&(e.query=t.query)):e.host&&(e.hostname=u(e.host).host),this.secure=null!=e.secure?e.secure:"undefined"!=typeof location&&"https:"===location.protocol,e.hostname&&!e.port&&(e.port=this.secure?"443":"80"),this.agent=e.agent||!1,this.hostname=e.hostname||("undefined"!=typeof location?location.hostname:"localhost"),this.port=e.port||("undefined"!=typeof location&&location.port?location.port:this.secure?443:80),this.query=e.query||{},"string"==typeof this.query&&(this.query=h.decode(this.query)),this.upgrade=!1!==e.upgrade,this.path=(e.path||"/engine.io").replace(/\/$/,"")+"/",this.forceJSONP=!!e.forceJSONP,this.jsonp=!1!==e.jsonp,this.forceBase64=!!e.forceBase64,this.enablesXDR=!!e.enablesXDR,this.timestampParam=e.timestampParam||"t",this.timestampRequests=e.timestampRequests,this.transports=e.transports||["polling","websocket"],this.transportOptions=e.transportOptions||{},this.readyState="",this.writeBuffer=[],this.prevBufferLen=0,this.policyPort=e.policyPort||843,this.rememberUpgrade=e.rememberUpgrade||!1,this.binaryType=null,this.onlyBinaryUpgrades=e.onlyBinaryUpgrades,this.perMessageDeflate=!1!==e.perMessageDeflate&&(e.perMessageDeflate||{}),!0===this.perMessageDeflate&&(this.perMessageDeflate={}),this.perMessageDeflate&&null==this.perMessageDeflate.threshold&&(this.perMessageDeflate.threshold=1024),this.pfx=e.pfx||null,this.key=e.key||null,this.passphrase=e.passphrase||null,this.cert=e.cert||null,this.ca=e.ca||null,this.ciphers=e.ciphers||null,this.rejectUnauthorized=void 0===e.rejectUnauthorized||e.rejectUnauthorized,this.forceNode=!!e.forceNode,this.isReactNative="undefined"!=typeof navigator&&"string"==typeof navigator.product&&"reactnative"===navigator.product.toLowerCase(),("undefined"==typeof self||this.isReactNative)&&(e.extraHeaders&&Object.keys(e.extraHeaders).length>0&&(this.extraHeaders=e.extraHeaders),e.localAddress&&(this.localAddress=e.localAddress)),this.id=null,this.upgrades=null,this.pingInterval=null,this.pingTimeout=null,this.pingIntervalTimer=null,this.pingTimeoutTimer=null,void this.open()):new r(t,e)}function o(t){var e={};for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e}var i=n(15),s=n(8),a=n(3)("engine.io-client:socket"),c=n(35),p=n(21),u=n(2),h=n(29);t.exports=r,r.priorWebsocketSuccess=!1,s(r.prototype),r.protocol=p.protocol,r.Socket=r,r.Transport=n(20),r.transports=n(15),r.parser=n(21),r.prototype.createTransport=function(t){a('creating transport "%s"',t);var e=o(this.query);e.EIO=p.protocol,e.transport=t;var n=this.transportOptions[t]||{};this.id&&(e.sid=this.id);var r=new i[t]({query:e,socket:this,agent:n.agent||this.agent,hostname:n.hostname||this.hostname,port:n.port||this.port,secure:n.secure||this.secure,path:n.path||this.path,forceJSONP:n.forceJSONP||this.forceJSONP,jsonp:n.jsonp||this.jsonp,forceBase64:n.forceBase64||this.forceBase64,enablesXDR:n.enablesXDR||this.enablesXDR,timestampRequests:n.timestampRequests||this.timestampRequests,timestampParam:n.timestampParam||this.timestampParam,policyPort:n.policyPort||this.policyPort,pfx:n.pfx||this.pfx,key:n.key||this.key,passphrase:n.passphrase||this.passphrase,cert:n.cert||this.cert,ca:n.ca||this.ca,ciphers:n.ciphers||this.ciphers,rejectUnauthorized:n.rejectUnauthorized||this.rejectUnauthorized,perMessageDeflate:n.perMessageDeflate||this.perMessageDeflate,extraHeaders:n.extraHeaders||this.extraHeaders,forceNode:n.forceNode||this.forceNode,localAddress:n.localAddress||this.localAddress,requestTimeout:n.requestTimeout||this.requestTimeout,protocols:n.protocols||void 0,isReactNative:this.isReactNative});return r},r.prototype.open=function(){var t;if(this.rememberUpgrade&&r.priorWebsocketSuccess&&this.transports.indexOf("websocket")!==-1)t="websocket";else{if(0===this.transports.length){var e=this;return void setTimeout(function(){e.emit("error","No transports available")},0)}t=this.transports[0]}this.readyState="opening";try{t=this.createTransport(t)}catch(n){return this.transports.shift(),void this.open()}t.open(),this.setTransport(t)},r.prototype.setTransport=function(t){a("setting transport %s",t.name);var e=this;this.transport&&(a("clearing existing transport %s",this.transport.name),this.transport.removeAllListeners()),this.transport=t,t.on("drain",function(){e.onDrain()}).on("packet",function(t){e.onPacket(t)}).on("error",function(t){e.onError(t)}).on("close",function(){e.onClose("transport close")})},r.prototype.probe=function(t){function e(){if(f.onlyBinaryUpgrades){var e=!this.supportsBinary&&f.transport.supportsBinary;h=h||e}h||(a('probe transport "%s" opened',t),u.send([{type:"ping",data:"probe"}]),u.once("packet",function(e){if(!h)if("pong"===e.type&&"probe"===e.data){if(a('probe transport "%s" pong',t),f.upgrading=!0,f.emit("upgrading",u),!u)return;r.priorWebsocketSuccess="websocket"===u.name,a('pausing current transport "%s"',f.transport.name),f.transport.pause(function(){h||"closed"!==f.readyState&&(a("changing transport and sending upgrade packet"),p(),f.setTransport(u),u.send([{type:"upgrade"}]),f.emit("upgrade",u),u=null,f.upgrading=!1,f.flush())})}else{a('probe transport "%s" failed',t);var n=new Error("probe error");n.transport=u.name,f.emit("upgradeError",n)}}))}function n(){h||(h=!0,p(),u.close(),u=null)}function o(e){var r=new Error("probe error: "+e);r.transport=u.name,n(),a('probe transport "%s" failed because of error: %s',t,e),f.emit("upgradeError",r)}function i(){o("transport closed")}function s(){o("socket closed")}function c(t){u&&t.name!==u.name&&(a('"%s" works - aborting "%s"',t.name,u.name),n())}function p(){u.removeListener("open",e),u.removeListener("error",o),u.removeListener("close",i),f.removeListener("close",s),f.removeListener("upgrading",c)}a('probing transport "%s"',t);var u=this.createTransport(t,{probe:1}),h=!1,f=this;r.priorWebsocketSuccess=!1,u.once("open",e),u.once("error",o),u.once("close",i),this.once("close",s),this.once("upgrading",c),u.open()},r.prototype.onOpen=function(){if(a("socket open"),this.readyState="open",r.priorWebsocketSuccess="websocket"===this.transport.name,this.emit("open"),this.flush(),"open"===this.readyState&&this.upgrade&&this.transport.pause){a("starting upgrade probes");for(var t=0,e=this.upgrades.length;t<e;t++)this.probe(this.upgrades[t])}},r.prototype.onPacket=function(t){if("opening"===this.readyState||"open"===this.readyState||"closing"===this.readyState)switch(a('socket receive: type "%s", data "%s"',t.type,t.data),this.emit("packet",t),this.emit("heartbeat"),t.type){case"open":this.onHandshake(JSON.parse(t.data));break;case"pong":this.setPing(),this.emit("pong");break;case"error":var e=new Error("server error");e.code=t.data,this.onError(e);break;case"message":this.emit("data",t.data),this.emit("message",t.data)}else a('packet received with socket readyState "%s"',this.readyState)},r.prototype.onHandshake=function(t){this.emit("handshake",t),this.id=t.sid,this.transport.query.sid=t.sid,this.upgrades=this.filterUpgrades(t.upgrades),this.pingInterval=t.pingInterval,this.pingTimeout=t.pingTimeout,this.onOpen(),"closed"!==this.readyState&&(this.setPing(),this.removeListener("heartbeat",this.onHeartbeat),this.on("heartbeat",this.onHeartbeat))},r.prototype.onHeartbeat=function(t){clearTimeout(this.pingTimeoutTimer);var e=this;e.pingTimeoutTimer=setTimeout(function(){"closed"!==e.readyState&&e.onClose("ping timeout")},t||e.pingInterval+e.pingTimeout)},r.prototype.setPing=function(){var t=this;clearTimeout(t.pingIntervalTimer),t.pingIntervalTimer=setTimeout(function(){a("writing ping packet - expecting pong within %sms",t.pingTimeout),t.ping(),t.onHeartbeat(t.pingTimeout)},t.pingInterval)},r.prototype.ping=function(){var t=this;this.sendPacket("ping",function(){t.emit("ping")})},r.prototype.onDrain=function(){this.writeBuffer.splice(0,this.prevBufferLen),this.prevBufferLen=0,0===this.writeBuffer.length?this.emit("drain"):this.flush()},r.prototype.flush=function(){"closed"!==this.readyState&&this.transport.writable&&!this.upgrading&&this.writeBuffer.length&&(a("flushing %d packets in socket",this.writeBuffer.length),this.transport.send(this.writeBuffer),this.prevBufferLen=this.writeBuffer.length,this.emit("flush"))},r.prototype.write=r.prototype.send=function(t,e,n){return this.sendPacket("message",t,e,n),this},r.prototype.sendPacket=function(t,e,n,r){if("function"==typeof e&&(r=e,e=void 0),"function"==typeof n&&(r=n,n=null),"closing"!==this.readyState&&"closed"!==this.readyState){n=n||{},n.compress=!1!==n.compress;var o={type:t,data:e,options:n};this.emit("packetCreate",o),this.writeBuffer.push(o),r&&this.once("flush",r),this.flush()}},r.prototype.close=function(){function t(){r.onClose("forced close"),a("socket closing - telling transport to close"),r.transport.close()}function e(){r.removeListener("upgrade",e),r.removeListener("upgradeError",e),t()}function n(){r.once("upgrade",e),r.once("upgradeError",e)}if("opening"===this.readyState||"open"===this.readyState){this.readyState="closing";var r=this;this.writeBuffer.length?this.once("drain",function(){this.upgrading?n():t()}):this.upgrading?n():t()}return this},r.prototype.onError=function(t){a("socket error %j",t),r.priorWebsocketSuccess=!1,this.emit("error",t),this.onClose("transport error",t)},r.prototype.onClose=function(t,e){if("opening"===this.readyState||"open"===this.readyState||"closing"===this.readyState){a('socket close with reason: "%s"',t);var n=this;clearTimeout(this.pingIntervalTimer),clearTimeout(this.pingTimeoutTimer),this.transport.removeAllListeners("close"),this.transport.close(),this.transport.removeAllListeners(),this.readyState="closed",this.id=null,this.emit("close",t,e),n.writeBuffer=[],n.prevBufferLen=0}},r.prototype.filterUpgrades=function(t){for(var e=[],n=0,r=t.length;n<r;n++)~c(this.transports,t[n])&&e.push(t[n]);return e}},function(t,e,n){function r(t){var e,n=!1,r=!1,a=!1!==t.jsonp;
if("undefined"!=typeof location){var c="https:"===location.protocol,p=location.port;p||(p=c?443:80),n=t.hostname!==location.hostname||p!==t.port,r=t.secure!==c}if(t.xdomain=n,t.xscheme=r,e=new o(t),"open"in e&&!t.forceJSONP)return new i(t);if(!a)throw new Error("JSONP disabled");return new s(t)}var o=n(16),i=n(18),s=n(32),a=n(33);e.polling=r,e.websocket=a},function(t,e,n){var r=n(17);t.exports=function(t){var e=t.xdomain,n=t.xscheme,o=t.enablesXDR;try{if("undefined"!=typeof XMLHttpRequest&&(!e||r))return new XMLHttpRequest}catch(i){}try{if("undefined"!=typeof XDomainRequest&&!n&&o)return new XDomainRequest}catch(i){}if(!e)try{return new(self[["Active"].concat("Object").join("X")])("Microsoft.XMLHTTP")}catch(i){}}},function(t,e){try{t.exports="undefined"!=typeof XMLHttpRequest&&"withCredentials"in new XMLHttpRequest}catch(n){t.exports=!1}},function(t,e,n){function r(){}function o(t){if(c.call(this,t),this.requestTimeout=t.requestTimeout,this.extraHeaders=t.extraHeaders,"undefined"!=typeof location){var e="https:"===location.protocol,n=location.port;n||(n=e?443:80),this.xd="undefined"!=typeof location&&t.hostname!==location.hostname||n!==t.port,this.xs=t.secure!==e}}function i(t){this.method=t.method||"GET",this.uri=t.uri,this.xd=!!t.xd,this.xs=!!t.xs,this.async=!1!==t.async,this.data=void 0!==t.data?t.data:null,this.agent=t.agent,this.isBinary=t.isBinary,this.supportsBinary=t.supportsBinary,this.enablesXDR=t.enablesXDR,this.requestTimeout=t.requestTimeout,this.pfx=t.pfx,this.key=t.key,this.passphrase=t.passphrase,this.cert=t.cert,this.ca=t.ca,this.ciphers=t.ciphers,this.rejectUnauthorized=t.rejectUnauthorized,this.extraHeaders=t.extraHeaders,this.create()}function s(){for(var t in i.requests)i.requests.hasOwnProperty(t)&&i.requests[t].abort()}var a=n(16),c=n(19),p=n(8),u=n(30),h=n(3)("engine.io-client:polling-xhr");if(t.exports=o,t.exports.Request=i,u(o,c),o.prototype.supportsBinary=!0,o.prototype.request=function(t){return t=t||{},t.uri=this.uri(),t.xd=this.xd,t.xs=this.xs,t.agent=this.agent||!1,t.supportsBinary=this.supportsBinary,t.enablesXDR=this.enablesXDR,t.pfx=this.pfx,t.key=this.key,t.passphrase=this.passphrase,t.cert=this.cert,t.ca=this.ca,t.ciphers=this.ciphers,t.rejectUnauthorized=this.rejectUnauthorized,t.requestTimeout=this.requestTimeout,t.extraHeaders=this.extraHeaders,new i(t)},o.prototype.doWrite=function(t,e){var n="string"!=typeof t&&void 0!==t,r=this.request({method:"POST",data:t,isBinary:n}),o=this;r.on("success",e),r.on("error",function(t){o.onError("xhr post error",t)}),this.sendXhr=r},o.prototype.doPoll=function(){h("xhr poll");var t=this.request(),e=this;t.on("data",function(t){e.onData(t)}),t.on("error",function(t){e.onError("xhr poll error",t)}),this.pollXhr=t},p(i.prototype),i.prototype.create=function(){var t={agent:this.agent,xdomain:this.xd,xscheme:this.xs,enablesXDR:this.enablesXDR};t.pfx=this.pfx,t.key=this.key,t.passphrase=this.passphrase,t.cert=this.cert,t.ca=this.ca,t.ciphers=this.ciphers,t.rejectUnauthorized=this.rejectUnauthorized;var e=this.xhr=new a(t),n=this;try{h("xhr open %s: %s",this.method,this.uri),e.open(this.method,this.uri,this.async);try{if(this.extraHeaders){e.setDisableHeaderCheck&&e.setDisableHeaderCheck(!0);for(var r in this.extraHeaders)this.extraHeaders.hasOwnProperty(r)&&e.setRequestHeader(r,this.extraHeaders[r])}}catch(o){}if("POST"===this.method)try{this.isBinary?e.setRequestHeader("Content-type","application/octet-stream"):e.setRequestHeader("Content-type","text/plain;charset=UTF-8")}catch(o){}try{e.setRequestHeader("Accept","*/*")}catch(o){}"withCredentials"in e&&(e.withCredentials=!0),this.requestTimeout&&(e.timeout=this.requestTimeout),this.hasXDR()?(e.onload=function(){n.onLoad()},e.onerror=function(){n.onError(e.responseText)}):e.onreadystatechange=function(){if(2===e.readyState)try{var t=e.getResponseHeader("Content-Type");n.supportsBinary&&"application/octet-stream"===t&&(e.responseType="arraybuffer")}catch(r){}4===e.readyState&&(200===e.status||1223===e.status?n.onLoad():setTimeout(function(){n.onError(e.status)},0))},h("xhr data %s",this.data),e.send(this.data)}catch(o){return void setTimeout(function(){n.onError(o)},0)}"undefined"!=typeof document&&(this.index=i.requestsCount++,i.requests[this.index]=this)},i.prototype.onSuccess=function(){this.emit("success"),this.cleanup()},i.prototype.onData=function(t){this.emit("data",t),this.onSuccess()},i.prototype.onError=function(t){this.emit("error",t),this.cleanup(!0)},i.prototype.cleanup=function(t){if("undefined"!=typeof this.xhr&&null!==this.xhr){if(this.hasXDR()?this.xhr.onload=this.xhr.onerror=r:this.xhr.onreadystatechange=r,t)try{this.xhr.abort()}catch(e){}"undefined"!=typeof document&&delete i.requests[this.index],this.xhr=null}},i.prototype.onLoad=function(){var t;try{var e;try{e=this.xhr.getResponseHeader("Content-Type")}catch(n){}t="application/octet-stream"===e?this.xhr.response||this.xhr.responseText:this.xhr.responseText}catch(n){this.onError(n)}null!=t&&this.onData(t)},i.prototype.hasXDR=function(){return"undefined"!=typeof XDomainRequest&&!this.xs&&this.enablesXDR},i.prototype.abort=function(){this.cleanup()},i.requestsCount=0,i.requests={},"undefined"!=typeof document)if("function"==typeof attachEvent)attachEvent("onunload",s);else if("function"==typeof addEventListener){var f="onpagehide"in self?"pagehide":"unload";addEventListener(f,s,!1)}},function(t,e,n){function r(t){var e=t&&t.forceBase64;u&&!e||(this.supportsBinary=!1),o.call(this,t)}var o=n(20),i=n(29),s=n(21),a=n(30),c=n(31),p=n(3)("engine.io-client:polling");t.exports=r;var u=function(){var t=n(16),e=new t({xdomain:!1});return null!=e.responseType}();a(r,o),r.prototype.name="polling",r.prototype.doOpen=function(){this.poll()},r.prototype.pause=function(t){function e(){p("paused"),n.readyState="paused",t()}var n=this;if(this.readyState="pausing",this.polling||!this.writable){var r=0;this.polling&&(p("we are currently polling - waiting to pause"),r++,this.once("pollComplete",function(){p("pre-pause polling complete"),--r||e()})),this.writable||(p("we are currently writing - waiting to pause"),r++,this.once("drain",function(){p("pre-pause writing complete"),--r||e()}))}else e()},r.prototype.poll=function(){p("polling"),this.polling=!0,this.doPoll(),this.emit("poll")},r.prototype.onData=function(t){var e=this;p("polling got data %s",t);var n=function(t,n,r){return"opening"===e.readyState&&e.onOpen(),"close"===t.type?(e.onClose(),!1):void e.onPacket(t)};s.decodePayload(t,this.socket.binaryType,n),"closed"!==this.readyState&&(this.polling=!1,this.emit("pollComplete"),"open"===this.readyState?this.poll():p('ignoring poll - transport state "%s"',this.readyState))},r.prototype.doClose=function(){function t(){p("writing close packet"),e.write([{type:"close"}])}var e=this;"open"===this.readyState?(p("transport open - closing"),t()):(p("transport not open - deferring close"),this.once("open",t))},r.prototype.write=function(t){var e=this;this.writable=!1;var n=function(){e.writable=!0,e.emit("drain")};s.encodePayload(t,this.supportsBinary,function(t){e.doWrite(t,n)})},r.prototype.uri=function(){var t=this.query||{},e=this.secure?"https":"http",n="";!1!==this.timestampRequests&&(t[this.timestampParam]=c()),this.supportsBinary||t.sid||(t.b64=1),t=i.encode(t),this.port&&("https"===e&&443!==Number(this.port)||"http"===e&&80!==Number(this.port))&&(n=":"+this.port),t.length&&(t="?"+t);var r=this.hostname.indexOf(":")!==-1;return e+"://"+(r?"["+this.hostname+"]":this.hostname)+n+this.path+t}},function(t,e,n){function r(t){this.path=t.path,this.hostname=t.hostname,this.port=t.port,this.secure=t.secure,this.query=t.query,this.timestampParam=t.timestampParam,this.timestampRequests=t.timestampRequests,this.readyState="",this.agent=t.agent||!1,this.socket=t.socket,this.enablesXDR=t.enablesXDR,this.pfx=t.pfx,this.key=t.key,this.passphrase=t.passphrase,this.cert=t.cert,this.ca=t.ca,this.ciphers=t.ciphers,this.rejectUnauthorized=t.rejectUnauthorized,this.forceNode=t.forceNode,this.isReactNative=t.isReactNative,this.extraHeaders=t.extraHeaders,this.localAddress=t.localAddress}var o=n(21),i=n(8);t.exports=r,i(r.prototype),r.prototype.onError=function(t,e){var n=new Error(t);return n.type="TransportError",n.description=e,this.emit("error",n),this},r.prototype.open=function(){return"closed"!==this.readyState&&""!==this.readyState||(this.readyState="opening",this.doOpen()),this},r.prototype.close=function(){return"opening"!==this.readyState&&"open"!==this.readyState||(this.doClose(),this.onClose()),this},r.prototype.send=function(t){if("open"!==this.readyState)throw new Error("Transport not open");this.write(t)},r.prototype.onOpen=function(){this.readyState="open",this.writable=!0,this.emit("open")},r.prototype.onData=function(t){var e=o.decodePacket(t,this.socket.binaryType);this.onPacket(e)},r.prototype.onPacket=function(t){this.emit("packet",t)},r.prototype.onClose=function(){this.readyState="closed",this.emit("close")}},function(t,e,n){function r(t,n){var r="b"+e.packets[t.type]+t.data.data;return n(r)}function o(t,n,r){if(!n)return e.encodeBase64Packet(t,r);var o=t.data,i=new Uint8Array(o),s=new Uint8Array(1+o.byteLength);s[0]=v[t.type];for(var a=0;a<i.length;a++)s[a+1]=i[a];return r(s.buffer)}function i(t,n,r){if(!n)return e.encodeBase64Packet(t,r);var o=new FileReader;return o.onload=function(){e.encodePacket({type:t.type,data:o.result},n,!0,r)},o.readAsArrayBuffer(t.data)}function s(t,n,r){if(!n)return e.encodeBase64Packet(t,r);if(g)return i(t,n,r);var o=new Uint8Array(1);o[0]=v[t.type];var s=new k([o.buffer,t.data]);return r(s)}function a(t){try{t=d.decode(t,{strict:!1})}catch(e){return!1}return t}function c(t,e,n){for(var r=new Array(t.length),o=l(t.length,n),i=function(t,n,o){e(n,function(e,n){r[t]=n,o(e,r)})},s=0;s<t.length;s++)i(s,t[s],o)}var p,u=n(22),h=n(23),f=n(24),l=n(25),d=n(26);"undefined"!=typeof ArrayBuffer&&(p=n(27));var y="undefined"!=typeof navigator&&/Android/i.test(navigator.userAgent),m="undefined"!=typeof navigator&&/PhantomJS/i.test(navigator.userAgent),g=y||m;e.protocol=3;var v=e.packets={open:0,close:1,ping:2,pong:3,message:4,upgrade:5,noop:6},b=u(v),w={type:"error",data:"parser error"},k=n(28);e.encodePacket=function(t,e,n,i){"function"==typeof e&&(i=e,e=!1),"function"==typeof n&&(i=n,n=null);var a=void 0===t.data?void 0:t.data.buffer||t.data;if("undefined"!=typeof ArrayBuffer&&a instanceof ArrayBuffer)return o(t,e,i);if("undefined"!=typeof k&&a instanceof k)return s(t,e,i);if(a&&a.base64)return r(t,i);var c=v[t.type];return void 0!==t.data&&(c+=n?d.encode(String(t.data),{strict:!1}):String(t.data)),i(""+c)},e.encodeBase64Packet=function(t,n){var r="b"+e.packets[t.type];if("undefined"!=typeof k&&t.data instanceof k){var o=new FileReader;return o.onload=function(){var t=o.result.split(",")[1];n(r+t)},o.readAsDataURL(t.data)}var i;try{i=String.fromCharCode.apply(null,new Uint8Array(t.data))}catch(s){for(var a=new Uint8Array(t.data),c=new Array(a.length),p=0;p<a.length;p++)c[p]=a[p];i=String.fromCharCode.apply(null,c)}return r+=btoa(i),n(r)},e.decodePacket=function(t,n,r){if(void 0===t)return w;if("string"==typeof t){if("b"===t.charAt(0))return e.decodeBase64Packet(t.substr(1),n);if(r&&(t=a(t),t===!1))return w;var o=t.charAt(0);return Number(o)==o&&b[o]?t.length>1?{type:b[o],data:t.substring(1)}:{type:b[o]}:w}var i=new Uint8Array(t),o=i[0],s=f(t,1);return k&&"blob"===n&&(s=new k([s])),{type:b[o],data:s}},e.decodeBase64Packet=function(t,e){var n=b[t.charAt(0)];if(!p)return{type:n,data:{base64:!0,data:t.substr(1)}};var r=p.decode(t.substr(1));return"blob"===e&&k&&(r=new k([r])),{type:n,data:r}},e.encodePayload=function(t,n,r){function o(t){return t.length+":"+t}function i(t,r){e.encodePacket(t,!!s&&n,!1,function(t){r(null,o(t))})}"function"==typeof n&&(r=n,n=null);var s=h(t);return n&&s?k&&!g?e.encodePayloadAsBlob(t,r):e.encodePayloadAsArrayBuffer(t,r):t.length?void c(t,i,function(t,e){return r(e.join(""))}):r("0:")},e.decodePayload=function(t,n,r){if("string"!=typeof t)return e.decodePayloadAsBinary(t,n,r);"function"==typeof n&&(r=n,n=null);var o;if(""===t)return r(w,0,1);for(var i,s,a="",c=0,p=t.length;c<p;c++){var u=t.charAt(c);if(":"===u){if(""===a||a!=(i=Number(a)))return r(w,0,1);if(s=t.substr(c+1,i),a!=s.length)return r(w,0,1);if(s.length){if(o=e.decodePacket(s,n,!1),w.type===o.type&&w.data===o.data)return r(w,0,1);var h=r(o,c+i,p);if(!1===h)return}c+=i,a=""}else a+=u}return""!==a?r(w,0,1):void 0},e.encodePayloadAsArrayBuffer=function(t,n){function r(t,n){e.encodePacket(t,!0,!0,function(t){return n(null,t)})}return t.length?void c(t,r,function(t,e){var r=e.reduce(function(t,e){var n;return n="string"==typeof e?e.length:e.byteLength,t+n.toString().length+n+2},0),o=new Uint8Array(r),i=0;return e.forEach(function(t){var e="string"==typeof t,n=t;if(e){for(var r=new Uint8Array(t.length),s=0;s<t.length;s++)r[s]=t.charCodeAt(s);n=r.buffer}e?o[i++]=0:o[i++]=1;for(var a=n.byteLength.toString(),s=0;s<a.length;s++)o[i++]=parseInt(a[s]);o[i++]=255;for(var r=new Uint8Array(n),s=0;s<r.length;s++)o[i++]=r[s]}),n(o.buffer)}):n(new ArrayBuffer(0))},e.encodePayloadAsBlob=function(t,n){function r(t,n){e.encodePacket(t,!0,!0,function(t){var e=new Uint8Array(1);if(e[0]=1,"string"==typeof t){for(var r=new Uint8Array(t.length),o=0;o<t.length;o++)r[o]=t.charCodeAt(o);t=r.buffer,e[0]=0}for(var i=t instanceof ArrayBuffer?t.byteLength:t.size,s=i.toString(),a=new Uint8Array(s.length+1),o=0;o<s.length;o++)a[o]=parseInt(s[o]);if(a[s.length]=255,k){var c=new k([e.buffer,a.buffer,t]);n(null,c)}})}c(t,r,function(t,e){return n(new k(e))})},e.decodePayloadAsBinary=function(t,n,r){"function"==typeof n&&(r=n,n=null);for(var o=t,i=[];o.byteLength>0;){for(var s=new Uint8Array(o),a=0===s[0],c="",p=1;255!==s[p];p++){if(c.length>310)return r(w,0,1);c+=s[p]}o=f(o,2+c.length),c=parseInt(c);var u=f(o,0,c);if(a)try{u=String.fromCharCode.apply(null,new Uint8Array(u))}catch(h){var l=new Uint8Array(u);u="";for(var p=0;p<l.length;p++)u+=String.fromCharCode(l[p])}i.push(u),o=f(o,c)}var d=i.length;i.forEach(function(t,o){r(e.decodePacket(t,n,!0),o,d)})}},function(t,e){t.exports=Object.keys||function(t){var e=[],n=Object.prototype.hasOwnProperty;for(var r in t)n.call(t,r)&&e.push(r);return e}},function(t,e,n){function r(t){if(!t||"object"!=typeof t)return!1;if(o(t)){for(var e=0,n=t.length;e<n;e++)if(r(t[e]))return!0;return!1}if("function"==typeof Buffer&&Buffer.isBuffer&&Buffer.isBuffer(t)||"function"==typeof ArrayBuffer&&t instanceof ArrayBuffer||s&&t instanceof Blob||a&&t instanceof File)return!0;if(t.toJSON&&"function"==typeof t.toJSON&&1===arguments.length)return r(t.toJSON(),!0);for(var i in t)if(Object.prototype.hasOwnProperty.call(t,i)&&r(t[i]))return!0;return!1}var o=n(10),i=Object.prototype.toString,s="function"==typeof Blob||"undefined"!=typeof Blob&&"[object BlobConstructor]"===i.call(Blob),a="function"==typeof File||"undefined"!=typeof File&&"[object FileConstructor]"===i.call(File);t.exports=r},function(t,e){t.exports=function(t,e,n){var r=t.byteLength;if(e=e||0,n=n||r,t.slice)return t.slice(e,n);if(e<0&&(e+=r),n<0&&(n+=r),n>r&&(n=r),e>=r||e>=n||0===r)return new ArrayBuffer(0);for(var o=new Uint8Array(t),i=new Uint8Array(n-e),s=e,a=0;s<n;s++,a++)i[a]=o[s];return i.buffer}},function(t,e){function n(t,e,n){function o(t,r){if(o.count<=0)throw new Error("after called too many times");--o.count,t?(i=!0,e(t),e=n):0!==o.count||i||e(null,r)}var i=!1;return n=n||r,o.count=t,0===t?e():o}function r(){}t.exports=n},function(t,e){function n(t){for(var e,n,r=[],o=0,i=t.length;o<i;)e=t.charCodeAt(o++),e>=55296&&e<=56319&&o<i?(n=t.charCodeAt(o++),56320==(64512&n)?r.push(((1023&e)<<10)+(1023&n)+65536):(r.push(e),o--)):r.push(e);return r}function r(t){for(var e,n=t.length,r=-1,o="";++r<n;)e=t[r],e>65535&&(e-=65536,o+=d(e>>>10&1023|55296),e=56320|1023&e),o+=d(e);return o}function o(t,e){if(t>=55296&&t<=57343){if(e)throw Error("Lone surrogate U+"+t.toString(16).toUpperCase()+" is not a scalar value");return!1}return!0}function i(t,e){return d(t>>e&63|128)}function s(t,e){if(0==(4294967168&t))return d(t);var n="";return 0==(4294965248&t)?n=d(t>>6&31|192):0==(4294901760&t)?(o(t,e)||(t=65533),n=d(t>>12&15|224),n+=i(t,6)):0==(4292870144&t)&&(n=d(t>>18&7|240),n+=i(t,12),n+=i(t,6)),n+=d(63&t|128)}function a(t,e){e=e||{};for(var r,o=!1!==e.strict,i=n(t),a=i.length,c=-1,p="";++c<a;)r=i[c],p+=s(r,o);return p}function c(){if(l>=f)throw Error("Invalid byte index");var t=255&h[l];if(l++,128==(192&t))return 63&t;throw Error("Invalid continuation byte")}function p(t){var e,n,r,i,s;if(l>f)throw Error("Invalid byte index");if(l==f)return!1;if(e=255&h[l],l++,0==(128&e))return e;if(192==(224&e)){if(n=c(),s=(31&e)<<6|n,s>=128)return s;throw Error("Invalid continuation byte")}if(224==(240&e)){if(n=c(),r=c(),s=(15&e)<<12|n<<6|r,s>=2048)return o(s,t)?s:65533;throw Error("Invalid continuation byte")}if(240==(248&e)&&(n=c(),r=c(),i=c(),s=(7&e)<<18|n<<12|r<<6|i,s>=65536&&s<=1114111))return s;throw Error("Invalid UTF-8 detected")}function u(t,e){e=e||{};var o=!1!==e.strict;h=n(t),f=h.length,l=0;for(var i,s=[];(i=p(o))!==!1;)s.push(i);return r(s)}/*! https://mths.be/utf8js v2.1.2 by @mathias */
var h,f,l,d=String.fromCharCode;t.exports={version:"2.1.2",encode:a,decode:u}},function(t,e){!function(){"use strict";for(var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",n=new Uint8Array(256),r=0;r<t.length;r++)n[t.charCodeAt(r)]=r;e.encode=function(e){var n,r=new Uint8Array(e),o=r.length,i="";for(n=0;n<o;n+=3)i+=t[r[n]>>2],i+=t[(3&r[n])<<4|r[n+1]>>4],i+=t[(15&r[n+1])<<2|r[n+2]>>6],i+=t[63&r[n+2]];return o%3===2?i=i.substring(0,i.length-1)+"=":o%3===1&&(i=i.substring(0,i.length-2)+"=="),i},e.decode=function(t){var e,r,o,i,s,a=.75*t.length,c=t.length,p=0;"="===t[t.length-1]&&(a--,"="===t[t.length-2]&&a--);var u=new ArrayBuffer(a),h=new Uint8Array(u);for(e=0;e<c;e+=4)r=n[t.charCodeAt(e)],o=n[t.charCodeAt(e+1)],i=n[t.charCodeAt(e+2)],s=n[t.charCodeAt(e+3)],h[p++]=r<<2|o>>4,h[p++]=(15&o)<<4|i>>2,h[p++]=(3&i)<<6|63&s;return u}}()},function(t,e){function n(t){return t.map(function(t){if(t.buffer instanceof ArrayBuffer){var e=t.buffer;if(t.byteLength!==e.byteLength){var n=new Uint8Array(t.byteLength);n.set(new Uint8Array(e,t.byteOffset,t.byteLength)),e=n.buffer}return e}return t})}function r(t,e){e=e||{};var r=new i;return n(t).forEach(function(t){r.append(t)}),e.type?r.getBlob(e.type):r.getBlob()}function o(t,e){return new Blob(n(t),e||{})}var i="undefined"!=typeof i?i:"undefined"!=typeof WebKitBlobBuilder?WebKitBlobBuilder:"undefined"!=typeof MSBlobBuilder?MSBlobBuilder:"undefined"!=typeof MozBlobBuilder&&MozBlobBuilder,s=function(){try{var t=new Blob(["hi"]);return 2===t.size}catch(e){return!1}}(),a=s&&function(){try{var t=new Blob([new Uint8Array([1,2])]);return 2===t.size}catch(e){return!1}}(),c=i&&i.prototype.append&&i.prototype.getBlob;"undefined"!=typeof Blob&&(r.prototype=Blob.prototype,o.prototype=Blob.prototype),t.exports=function(){return s?a?Blob:o:c?r:void 0}()},function(t,e){e.encode=function(t){var e="";for(var n in t)t.hasOwnProperty(n)&&(e.length&&(e+="&"),e+=encodeURIComponent(n)+"="+encodeURIComponent(t[n]));return e},e.decode=function(t){for(var e={},n=t.split("&"),r=0,o=n.length;r<o;r++){var i=n[r].split("=");e[decodeURIComponent(i[0])]=decodeURIComponent(i[1])}return e}},function(t,e){t.exports=function(t,e){var n=function(){};n.prototype=e.prototype,t.prototype=new n,t.prototype.constructor=t}},function(t,e){"use strict";function n(t){var e="";do e=s[t%a]+e,t=Math.floor(t/a);while(t>0);return e}function r(t){var e=0;for(u=0;u<t.length;u++)e=e*a+c[t.charAt(u)];return e}function o(){var t=n(+new Date);return t!==i?(p=0,i=t):t+"."+n(p++)}for(var i,s="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_".split(""),a=64,c={},p=0,u=0;u<a;u++)c[s[u]]=u;o.encode=n,o.decode=r,t.exports=o},function(t,e,n){(function(e){function r(){}function o(){return"undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof e?e:{}}function i(t){if(s.call(this,t),this.query=this.query||{},!c){var e=o();c=e.___eio=e.___eio||[]}this.index=c.length;var n=this;c.push(function(t){n.onData(t)}),this.query.j=this.index,"function"==typeof addEventListener&&addEventListener("beforeunload",function(){n.script&&(n.script.onerror=r)},!1)}var s=n(19),a=n(30);t.exports=i;var c,p=/\n/g,u=/\\n/g;a(i,s),i.prototype.supportsBinary=!1,i.prototype.doClose=function(){this.script&&(this.script.parentNode.removeChild(this.script),this.script=null),this.form&&(this.form.parentNode.removeChild(this.form),this.form=null,this.iframe=null),s.prototype.doClose.call(this)},i.prototype.doPoll=function(){var t=this,e=document.createElement("script");this.script&&(this.script.parentNode.removeChild(this.script),this.script=null),e.async=!0,e.src=this.uri(),e.onerror=function(e){t.onError("jsonp poll error",e)};var n=document.getElementsByTagName("script")[0];n?n.parentNode.insertBefore(e,n):(document.head||document.body).appendChild(e),this.script=e;var r="undefined"!=typeof navigator&&/gecko/i.test(navigator.userAgent);r&&setTimeout(function(){var t=document.createElement("iframe");document.body.appendChild(t),document.body.removeChild(t)},100)},i.prototype.doWrite=function(t,e){function n(){r(),e()}function r(){if(o.iframe)try{o.form.removeChild(o.iframe)}catch(t){o.onError("jsonp polling iframe removal error",t)}try{var e='<iframe src="javascript:0" name="'+o.iframeId+'">';i=document.createElement(e)}catch(t){i=document.createElement("iframe"),i.name=o.iframeId,i.src="javascript:0"}i.id=o.iframeId,o.form.appendChild(i),o.iframe=i}var o=this;if(!this.form){var i,s=document.createElement("form"),a=document.createElement("textarea"),c=this.iframeId="eio_iframe_"+this.index;s.className="socketio",s.style.position="absolute",s.style.top="-1000px",s.style.left="-1000px",s.target=c,s.method="POST",s.setAttribute("accept-charset","utf-8"),a.name="d",s.appendChild(a),document.body.appendChild(s),this.form=s,this.area=a}this.form.action=this.uri(),r(),t=t.replace(u,"\\\n"),this.area.value=t.replace(p,"\\n");try{this.form.submit()}catch(h){}this.iframe.attachEvent?this.iframe.onreadystatechange=function(){"complete"===o.iframe.readyState&&n()}:this.iframe.onload=n}}).call(e,function(){return this}())},function(t,e,n){function r(t){var e=t&&t.forceBase64;e&&(this.supportsBinary=!1),this.perMessageDeflate=t.perMessageDeflate,this.usingBrowserWebSocket=o&&!t.forceNode,this.protocols=t.protocols,this.usingBrowserWebSocket||(l=i),s.call(this,t)}var o,i,s=n(20),a=n(21),c=n(29),p=n(30),u=n(31),h=n(3)("engine.io-client:websocket");if("undefined"==typeof self)try{i=n(34)}catch(f){}else o=self.WebSocket||self.MozWebSocket;var l=o||i;t.exports=r,p(r,s),r.prototype.name="websocket",r.prototype.supportsBinary=!0,r.prototype.doOpen=function(){if(this.check()){var t=this.uri(),e=this.protocols,n={agent:this.agent,perMessageDeflate:this.perMessageDeflate};n.pfx=this.pfx,n.key=this.key,n.passphrase=this.passphrase,n.cert=this.cert,n.ca=this.ca,n.ciphers=this.ciphers,n.rejectUnauthorized=this.rejectUnauthorized,this.extraHeaders&&(n.headers=this.extraHeaders),this.localAddress&&(n.localAddress=this.localAddress);try{this.ws=this.usingBrowserWebSocket&&!this.isReactNative?e?new l(t,e):new l(t):new l(t,e,n)}catch(r){return this.emit("error",r)}void 0===this.ws.binaryType&&(this.supportsBinary=!1),this.ws.supports&&this.ws.supports.binary?(this.supportsBinary=!0,this.ws.binaryType="nodebuffer"):this.ws.binaryType="arraybuffer",this.addEventListeners()}},r.prototype.addEventListeners=function(){var t=this;this.ws.onopen=function(){t.onOpen()},this.ws.onclose=function(){t.onClose()},this.ws.onmessage=function(e){t.onData(e.data)},this.ws.onerror=function(e){t.onError("websocket error",e)}},r.prototype.write=function(t){function e(){n.emit("flush"),setTimeout(function(){n.writable=!0,n.emit("drain")},0)}var n=this;this.writable=!1;for(var r=t.length,o=0,i=r;o<i;o++)!function(t){a.encodePacket(t,n.supportsBinary,function(o){if(!n.usingBrowserWebSocket){var i={};if(t.options&&(i.compress=t.options.compress),n.perMessageDeflate){var s="string"==typeof o?Buffer.byteLength(o):o.length;s<n.perMessageDeflate.threshold&&(i.compress=!1)}}try{n.usingBrowserWebSocket?n.ws.send(o):n.ws.send(o,i)}catch(a){h("websocket closed before onclose event")}--r||e()})}(t[o])},r.prototype.onClose=function(){s.prototype.onClose.call(this)},r.prototype.doClose=function(){"undefined"!=typeof this.ws&&this.ws.close()},r.prototype.uri=function(){var t=this.query||{},e=this.secure?"wss":"ws",n="";this.port&&("wss"===e&&443!==Number(this.port)||"ws"===e&&80!==Number(this.port))&&(n=":"+this.port),this.timestampRequests&&(t[this.timestampParam]=u()),this.supportsBinary||(t.b64=1),t=c.encode(t),t.length&&(t="?"+t);var r=this.hostname.indexOf(":")!==-1;return e+"://"+(r?"["+this.hostname+"]":this.hostname)+n+this.path+t},r.prototype.check=function(){return!(!l||"__initialize"in l&&this.name===r.prototype.name)}},function(t,e){},function(t,e){var n=[].indexOf;t.exports=function(t,e){if(n)return t.indexOf(e);for(var r=0;r<t.length;++r)if(t[r]===e)return r;return-1}},function(t,e,n){"use strict";function r(t,e,n){this.io=t,this.nsp=e,this.json=this,this.ids=0,this.acks={},this.receiveBuffer=[],this.sendBuffer=[],this.connected=!1,this.disconnected=!0,this.flags={},n&&n.query&&(this.query=n.query),this.io.autoConnect&&this.open()}var o="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=n(7),s=n(8),a=n(37),c=n(38),p=n(39),u=n(3)("socket.io-client:socket"),h=n(29),f=n(23);t.exports=e=r;var l={connect:1,connect_error:1,connect_timeout:1,connecting:1,disconnect:1,error:1,reconnect:1,reconnect_attempt:1,reconnect_failed:1,reconnect_error:1,reconnecting:1,ping:1,pong:1},d=s.prototype.emit;s(r.prototype),r.prototype.subEvents=function(){if(!this.subs){var t=this.io;this.subs=[c(t,"open",p(this,"onopen")),c(t,"packet",p(this,"onpacket")),c(t,"close",p(this,"onclose"))]}},r.prototype.open=r.prototype.connect=function(){return this.connected?this:(this.subEvents(),this.io.open(),"open"===this.io.readyState&&this.onopen(),this.emit("connecting"),this)},r.prototype.send=function(){var t=a(arguments);return t.unshift("message"),this.emit.apply(this,t),this},r.prototype.emit=function(t){if(l.hasOwnProperty(t))return d.apply(this,arguments),this;var e=a(arguments),n={type:(void 0!==this.flags.binary?this.flags.binary:f(e))?i.BINARY_EVENT:i.EVENT,data:e};return n.options={},n.options.compress=!this.flags||!1!==this.flags.compress,"function"==typeof e[e.length-1]&&(u("emitting packet with ack id %d",this.ids),this.acks[this.ids]=e.pop(),n.id=this.ids++),this.connected?this.packet(n):this.sendBuffer.push(n),this.flags={},this},r.prototype.packet=function(t){t.nsp=this.nsp,this.io.packet(t)},r.prototype.onopen=function(){if(u("transport is open - connecting"),"/"!==this.nsp)if(this.query){var t="object"===o(this.query)?h.encode(this.query):this.query;u("sending connect packet with query %s",t),this.packet({type:i.CONNECT,query:t})}else this.packet({type:i.CONNECT})},r.prototype.onclose=function(t){u("close (%s)",t),this.connected=!1,this.disconnected=!0,delete this.id,this.emit("disconnect",t)},r.prototype.onpacket=function(t){var e=t.nsp===this.nsp,n=t.type===i.ERROR&&"/"===t.nsp;if(e||n)switch(t.type){case i.CONNECT:this.onconnect();break;case i.EVENT:this.onevent(t);break;case i.BINARY_EVENT:this.onevent(t);break;case i.ACK:this.onack(t);break;case i.BINARY_ACK:this.onack(t);break;case i.DISCONNECT:this.ondisconnect();break;case i.ERROR:this.emit("error",t.data)}},r.prototype.onevent=function(t){var e=t.data||[];u("emitting event %j",e),null!=t.id&&(u("attaching ack callback to event"),e.push(this.ack(t.id))),this.connected?d.apply(this,e):this.receiveBuffer.push(e)},r.prototype.ack=function(t){var e=this,n=!1;return function(){if(!n){n=!0;var r=a(arguments);u("sending ack %j",r),e.packet({type:f(r)?i.BINARY_ACK:i.ACK,id:t,data:r})}}},r.prototype.onack=function(t){var e=this.acks[t.id];"function"==typeof e?(u("calling ack %s with %j",t.id,t.data),e.apply(this,t.data),delete this.acks[t.id]):u("bad ack %s",t.id)},r.prototype.onconnect=function(){this.connected=!0,this.disconnected=!1,this.emit("connect"),this.emitBuffered()},r.prototype.emitBuffered=function(){var t;for(t=0;t<this.receiveBuffer.length;t++)d.apply(this,this.receiveBuffer[t]);for(this.receiveBuffer=[],t=0;t<this.sendBuffer.length;t++)this.packet(this.sendBuffer[t]);this.sendBuffer=[]},r.prototype.ondisconnect=function(){u("server disconnect (%s)",this.nsp),this.destroy(),this.onclose("io server disconnect")},r.prototype.destroy=function(){if(this.subs){for(var t=0;t<this.subs.length;t++)this.subs[t].destroy();this.subs=null}this.io.destroy(this)},r.prototype.close=r.prototype.disconnect=function(){return this.connected&&(u("performing disconnect (%s)",this.nsp),this.packet({type:i.DISCONNECT})),this.destroy(),this.connected&&this.onclose("io client disconnect"),this},r.prototype.compress=function(t){return this.flags.compress=t,this},r.prototype.binary=function(t){return this.flags.binary=t,this}},function(t,e){function n(t,e){var n=[];e=e||0;for(var r=e||0;r<t.length;r++)n[r-e]=t[r];return n}t.exports=n},function(t,e){"use strict";function n(t,e,n){return t.on(e,n),{destroy:function(){t.removeListener(e,n)}}}t.exports=n},function(t,e){var n=[].slice;t.exports=function(t,e){if("string"==typeof e&&(e=t[e]),"function"!=typeof e)throw new Error("bind() requires a function");var r=n.call(arguments,2);return function(){return e.apply(t,r.concat(n.call(arguments)))}}},function(t,e){function n(t){t=t||{},this.ms=t.min||100,this.max=t.max||1e4,this.factor=t.factor||2,this.jitter=t.jitter>0&&t.jitter<=1?t.jitter:0,this.attempts=0}t.exports=n,n.prototype.duration=function(){var t=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var e=Math.random(),n=Math.floor(e*this.jitter*t);t=0==(1&Math.floor(10*e))?t-n:t+n}return 0|Math.min(t,this.max)},n.prototype.reset=function(){this.attempts=0},n.prototype.setMin=function(t){this.ms=t},n.prototype.setMax=function(t){this.max=t},n.prototype.setJitter=function(t){this.jitter=t}}])});
//# sourceMappingURL=socket.io.js.map
================================================
FILE: game_resources/js/plugins/Nasty_Text_Pop_Events.js
================================================
//=============================================================================
// Nasty Text Pop Over Event
// Version: 1.2.1 - Added default offset x and y positioning in options
// Version: 1.2.0
//=============================================================================
var Imported = Imported || {};
Imported.Nasty_Event_Text_Pop = true;
var Nasty = Nasty || {};
//=============================================================================
/*:
* @plugindesc Make text over events, players and followers!
*<Nasty_Text_Pop_Over_Events>
* @author Nelderson
*
* @param Font Size 1
* @desc USize of the font to be displayed.
* @default 28
*
* @param Font Color 1
* @desc Color of the font
* @default #ffffff
*
* @param Outline Size 1
* @desc Size of the outline from the text
* @default 4
*
* @param Outline Color 1
* @desc Color of the outline on text.
* @default rgba(0, 0, 0, 0.5)
*
* @param Font Name 1
* @desc Name of the font you want to use.
* @default GameFont
*
* @param Font italic? 1
* @desc Do you want Italic font?
* @default false
*
* @param Time 1
* @desc Time before text disappers. Set to 0 for eternal.
* @default 120
*
* @param Offset_X 1
* @desc Default offset x for text.
* @default 0
*
* @param Offset_Y 1
* @desc Default offset y for text.
* @default 0
*
*@param =============
*
* @param Font Size 2
* @desc USize of the font to be displayed.
* @default 28
*
* @param Font Color 2
* @desc Color of the font
* @default #ffffff
*
* @param Outline Size 2
* @desc Size of the outline from the text
* @default 4
*
* @param Outline Color 2
* @desc Color of the outline on text.
* @default rgba(0, 0, 0, 0.5)
*
* @param Font Name 2
* @desc Name of the font you want to use.
* @default GameFont
*
* @param Font italic? 2
* @desc Do you want Italic font?
* @default false
*
* @param Time 2
* @desc Time before text disappers. Set to 0 for eternal.
* @default 120
*
* @param Offset_X 2
* @desc Default offset x for text.
* @default 0
*
* @param Offset_Y 2
* @desc Default offset y for text.
* @default 0
*
*@param =============
*
* @param Font Size 3
* @desc USize of the font to be displayed.
* @default 28
*
* @param Font Color 3
* @desc Color of the font
* @default #ffffff
*
* @param Outline Size 3
* @desc Size of the outline from the text
* @default 4
*
* @param Outline Color 3
* @desc Color of the outline on text.
* @default rgba(0, 0, 0, 0.5)
*
* @param Font Name 3
* @desc Name of the font you want to use.
* @default GameFont
*
* @param Font italic? 3
* @desc Do you want Italic font?
* @default false
*
* @param Time 3
* @desc Time before text disappers. Set to 0 for eternal.
* @default 120
*
* @param Offset_X 3
* @desc Default offset x for text.
* @default 0
*
* @param Offset_Y 3
* @desc Default offset y for text.
* @default 0
*
*@param =============
*
* @param Font Size 4
* @desc USize of the font to be displayed.
* @default 28
*
* @param Font Color 4
* @desc Color of the font
* @default #ffffff
*
* @param Outline Size 4
* @desc Size of the outline from the text
* @default 4
*
* @param Outline Color 4
* @desc Color of the outline on text.
* @default rgba(0, 0, 0, 0.5)
*
* @param Font Name 4
* @desc Name of the font you want to use.
* @default GameFont
*
* @param Font italic? 4
* @desc Do you want Italic font?
* @default false
*
* @param Time 4
* @desc Time before text disappers. Set to 0 for eternal.
* @default 120
*
* @param Offset_X 4
* @desc Default offset x for text.
* @default 0
*
* @param Offset_Y 4
* @desc Default offset y for text.
* @default 0
*
*@param =============
*
* @param Font Size 5
* @desc USize of the font to be displayed.
* @default 28
*
* @param Font Color 5
* @desc Color of the font
* @default #ffffff
*
* @param Outline Size 5
* @desc Size of the outline from the text
* @default 4
*
* @param Outline Color 5
* @desc Color of the outline on text.
* @default rgba(0, 0, 0, 0.5)
*
* @param Font Name 5
* @desc Name of the font you want to use.
* @default GameFont
*
* @param Font italic? 5
* @desc Do you want Italic font?
* @default false
*
* @param Time 5
* @desc Time before text disappers. Set to 0 for eternal.
* @default 120
*
* @param Offset_X 5
* @desc Default offset x for text.
* @default 0
*
* @param Offset_Y 5
* @desc Default offset y for text.
* @default 0
*
*@param =============
*
* @param Font Size 6
* @desc USize of the font to be displayed.
* @default 28
*
* @param Font Color 6
* @desc Color of the font
* @default #ffffff
*
* @param Outline Size 6
* @desc Size of the outline from the text
* @default 4
*
* @param Outline Color 6
* @desc Color of the outline on text.
* @default rgba(0, 0, 0, 0.5)
*
* @param Font Name 6
* @desc Name of the font you want to use.
* @default GameFont
*
* @param Font italic? 6
* @desc Do you want Italic font?
* @default false
*
* @param Time 6
* @desc Time before text disappers. Set to 0 for eternal.
* @default 120
*
* @param Offset_X 6
* @desc Default offset x for text.
* @default 0
*
* @param Offset_Y 6
* @desc Default offset y for text.
* @default 0
*
*@param =============
*
* @param Font Size 7
* @desc USize of the font to be displayed.
* @default 28
*
* @param Font Color 7
* @desc Color of the font
* @default #ffffff
*
* @param Outline Size 7
* @desc Size of the outline from the text
* @default 4
*
* @param Outline Color 7
* @desc Color of the outline on text.
* @default rgba(0, 0, 0, 0.5)
*
* @param Font Name 7
* @desc Name of the font you want to use.
* @default GameFont
*
* @param Font italic? 7
* @desc Do you want Italic font?
* @default false
*
* @param Time 7
* @desc Time before text disappers. Set to 0 for eternal.
* @default 120
*
* @param Offset_X 7
* @desc Default offset x for text.
* @default 0
*
* @param Offset_Y 7
* @desc Default offset y for text.
* @default 0
*
*@param =============
*
* @param Font Size 8
* @desc USize of the font to be displayed.
* @default 28
*
* @param Font Color 8
* @desc Color of the font
* @default #ffffff
*
* @param Outline Size 8
* @desc Size of the outline from the text
* @default 4
*
* @param Outline Color 8
* @desc Color of the outline on text.
* @default rgba(0, 0, 0, 0.5)
*
* @param Font Name 8
* @desc Name of the font you want to use.
* @default GameFont
*
* @param Font italic? 8
* @desc Do you want Italic font?
* @default false
*
* @param Time 8
* @desc Time before text disappers. Set to 0 for eternal.
* @default 120
*
* @param Offset_X 8
* @desc Default offset x for text.
* @default 0
*
* @param Offset_Y 8
* @desc Default offset y for text.
* @default 0
*
*@param =============
*
* @param Font Size 9
* @desc USize of the font to be displayed.
* @default 28
*
* @param Font Color 9
* @desc Color of the font
* @default #ffffff
*
* @param Outline Size 9
* @desc Size of the outline from the text
* @default 4
*
* @param Outline Color 9
* @desc Color of the outline on text.
* @default rgba(0, 0, 0, 0.5)
*
* @param Font Name 9
* @desc Name of the font you want to use.
* @default GameFont
*
* @param Font italic? 9
* @desc Do you want Italic font?
* @default false
*
* @param Time 9
* @desc Time before text disappers. Set to 0 for eternal.
* @default 120
*
* @param Offset_X 9
* @desc Default offset x for text.
* @default 0
*
* @param Offset_Y 9
* @desc Default offset y for text.
* @default 0
*
*@param =============
*
* @param Font Size 10
* @desc USize of the font to be displayed.
* @default 28
*
* @param Font Color 10
* @desc Color of the font
* @default #ffffff
*
* @param Outline Size 10
* @desc Size of the outline from the text
* @default 4
*
* @param Outline Color 10
* @desc Color of the outline on text.
* @default rgba(0, 0, 0, 0.5)
*
* @param Font Name 10
* @desc Name of the font you want to use.
* @default GameFont
*
* @param Font italic? 10
* @desc Do you want Italic font?
* @default false
*
* @param Time 10
* @desc Time before text disappers. Set to 0 for eternal.
* @default 120
*
* @param Offset_X 10
* @desc Default offset x for text.
* @default 0
*
* @param Offset_Y 10
* @desc Default offset y for text.
* @default 0
*
*@param =============
*
* @help
* ============================================================================
* Introduction and Instructions
* ============================================================================
*
* Want to make events on the map say something, but the message box crimps
* your style by pausing everything else going on? Then NASTY Text Pop
* might be the answer for you!
*
* You can call the text with the Plugin command:
*
* NastyTextPop ID# template# #ofFrames String of text here
*
* -ID#
* 0 = The event using the command
* 1-9999 = Event number on the map.
* -1 = Your player
* -2 = Follower 1
* -3 = Follower 2
* -4 = Follower 3
*
* -Template#
* This number coreponds to the plugin manager numbers for text size
* font name, outline width, etc.
*
* -#ofFrames
* Number of frames before the text disappers. 60 frames in a second
* Putting a 0 will hold the text there until the map is refreshed.
*
* -String of text here
* Place any text after the first 3 arguments, and it will all show
* on the specified EventID, Player or Follower.
*
* Ex. NastyTextPop -1 1 120 Tesing This!
*
* This would show "Testing This!" over the Player for 120
* frames and use the settings in the first plugin spot.
*
* As of Version 1.1.0 you can now use the Script Command:
*
* this.NastyTextPop({
* argument1: value
* argument2: value
* argument3: value
* etc..
* })
*
* Arguments you can use:
*
* text: "String Here" - What you want to pop up.
*
* id: Number -
* 0 = The event using the command
* 1-9999 = Event number on the map.
* -1 = Your player
* -2 = Follower 1
* -3 = Follower 2
* -4 = Follower 3
*
* template: Number - Template setup in plugin manager.
*
* windowOpacity: Number - Opacity of window. 0 is default.
*
* time: Number - Frames before text erases. 0 until map refreshes.
*
* font: 'FontName' - Change font
*
* fontsize: Number - Size of the font.
*
* fontcolor: 'String' - Color of text
*
* outlineColor: 'String' - Color of Outline text
*
* outlineWidth: Number - Outline width
*
* italic: true/false - Italic font?
*
* width: Number - Offset of Window width
*
* height: Number - Offset of Window height
*
* x: Number - Offset of x
*
* y: Number - Offset of y
*
* Ex: Place this in script call~
*
* this.NastyTextPop({
* time: 0,
* italic: true,
* windowOpacity: 255,
* fontsize: 28,
* outlineColor: '#ff2456',
* outlineWidth: 6,
* width: -600,
* height: 100,
* text: 'Test This Right? \n\\I[10] \nThis is kinda cool bruh!\nTry not to abuse it..',
* })
*
* HAVE FUN!
*/
//=============================================================================
//=============================================================================
// Parameter Variables
//=============================================================================
Nasty.Event_Text_Pop = Nasty.Event_Text_Pop || {};
(function ($) {
Nasty.Parameters = $plugins.filter(function(p)
{ return p.description.contains('<Nasty_Text_Pop_Over_Events>');
})[0].parameters;
Nasty.Param = Nasty.Param || {};
Nasty.Param.TextPop = [];
Nasty.Param.TextPop.push({
namepop_size: Number(Nasty.Parameters['Font Size 1']),
namepop_color: String(Nasty.Parameters['Font Color 1']),
namepop_outlineWidth: Number(Nasty.Parameters['Outline Size 1']),
namepop_outlineColor: String(Nasty.Parameters['Outline Color 1']),
namepop_font: String(Nasty.Parameters['Font Name 1']),
namepop_ital: String(Nasty.Parameters['Font italic? 1']),
namepop_time: Number(Nasty.Parameters['Time 1']),
namepop_offsetx: Number(Nasty.Parameters['Offset_X 1']),
namepop_offsety: Number(Nasty.Parameters['Offset_Y 1'])
});
Nasty.Param.TextPop.push({
namepop_size: Number(Nasty.Parameters['Font Size 2']),
namepop_color: String(Nasty.Parameters['Font Color 2']),
namepop_outlineWidth: Number(Nasty.Parameters['Outline Size 2']),
namepop_outlineColor: String(Nasty.Parameters['Outline Color 2']),
namepop_font: String(Nasty.Parameters['Font Name 2']),
namepop_ital: String(Nasty.Parameters['Font italic? 2']),
namepop_time: Number(Nasty.Parameters['Time 2']),
namepop_offsetx: Number(Nasty.Parameters['Offset_X 2']),
namepop_offsety: Number(Nasty.Parameters['Offset_Y 2'])
});
Nasty.Param.TextPop.push({
namepop_size: Number(Nasty.Parameters['Font Size 3']),
namepop_color: String(Nasty.Parameters['Font Color 3']),
namepop_outlineWidth: Number(Nasty.Parameters['Outline Size 3']),
namepop_outlineColor: String(Nasty.Parameters['Outline Color 3']),
namepop_font: String(Nasty.Parameters['Font Name 3']),
namepop_ital: String(Nasty.Parameters['Font italic? 3']),
namepop_time: Number(Nasty.Parameters['Time 3']),
namepop_offsetx: Number(Nasty.Parameters['Offset_X 3']),
namepop_offsety: Number(Nasty.Parameters['Offset_Y 3'])
});
Nasty.Param.TextPop.push({
namepop_size: Number(Nasty.Parameters['Font Size 4']),
namepop_color: String(Nasty.Parameters['Font Color 4']),
namepop_outlineWidth: Number(Nasty.Parameters['Outline Size 4']),
namepop_outlineColor: String(Nasty.Parameters['Outline Color 4']),
namepop_font: String(Nasty.Parameters['Font Name 4']),
namepop_ital: String(Nasty.Parameters['Font italic? 4']),
namepop_time: Number(Nasty.Parameters['Time 4']),
namepop_offsetx: Number(Nasty.Parameters['Offset_X 4']),
namepop_offsety: Number(Nasty.Parameters['Offset_Y 4'])
});
Nasty.Param.TextPop.push({
namepop_size: Number(Nasty.Parameters['Font Size 5']),
namepop_color: String(Nasty.Parameters['Font Color 5']),
namepop_outlineWidth: Number(Nasty.Parameters['Outline Size 5']),
namepop_outlineColor: String(Nasty.Parameters['Outline Color 5']),
namepop_font: String(Nasty.Parameters['Font Name 5']),
namepop_ital: String(Nasty.Parameters['Font italic? 5']),
namepop_time: Number(Nasty.Parameters['Time 5']),
namepop_offsetx: Number(Nasty.Parameters['Offset_X 5']),
namepop_offsety: Number(Nasty.Parameters['Offset_Y 5'])
});
Nasty.Param.TextPop.push({
namepop_size: Number(Nasty.Parameters['Font Size 6']),
namepop_color: String(Nasty.Parameters['Font Color 6']),
namepop_outlineWidth: Number(Nasty.Parameters['Outline Size 6']),
namepop_outlineColor: String(Nasty.Parameters['Outline Color 6']),
namepop_font: String(Nasty.Parameters['Font Name 6']),
namepop_ital: String(Nasty.Parameters['Font italic? 6']),
namepop_time: Number(Nasty.Parameters['Time 6']),
namepop_offsetx: Number(Nasty.Parameters['Offset_X 6']),
namepop_offsety: Number(Nasty.Parameters['Offset_Y 6'])
});
Nasty.Param.TextPop.push({
namepop_size: Number(Nasty.Parameters['Font Size 7']),
namepop_color: String(Nasty.Parameters['Font Color 7']),
namepop_outlineWidth: Number(Nasty.Parameters['Outline Size 7']),
namepop_outlineColor: String(Nasty.Parameters['Outline Color 7']),
namepop_font: String(Nasty.Parameters['Font Name 7']),
namepop_ital: String(Nasty.Parameters['Font italic? 7']),
namepop_time: Number(Nasty.Parameters['Time 7']),
namepop_offsetx: Number(Nasty.Parameters['Offset_X 7']),
namepop_offsety: Number(Nasty.Parameters['Offset_Y 7'])
});
Nasty.Param.TextPop.push({
namepop_size: Number(Nasty.Parameters['Font Size 8']),
namepop_color: String(Nasty.Parameters['Font Color 8']),
namepop_outlineWidth: Number(Nasty.Parameters['Outline Size 8']),
namepop_outlineColor: String(Nasty.Parameters['Outline Color 8']),
namepop_font: String(Nasty.Parameters['Font Name 8']),
namepop_ital: String(Nasty.Parameters['Font italic? 8']),
namepop_time: Number(Nasty.Parameters['Time 8']),
namepop_offsetx: Number(Nasty.Parameters['Offset_X 8']),
namepop_offsety: Number(Nasty.Parameters['Offset_Y 8'])
});
Nasty.Param.TextPop.push({
namepop_size: Number(Nasty.Parameters['Font Size 9']),
namepop_color: String(Nasty.Parameters['Font Color 9']),
namepop_outlineWidth: Number(Nasty.Parameters['Outline Size 9']),
namepop_outlineColor: String(Nasty.Parameters['Outline Color 9']),
namepop_font: String(Nasty.Parameters['Font Name 9']),
namepop_ital: String(Nasty.Parameters['Font italic? 9']),
namepop_time: Number(Nasty.Parameters['Time 9']),
namepop_offsetx: Number(Nasty.Parameters['Offset_X 9']),
namepop_offsety: Number(Nasty.Parameters['Offset_Y 9'])
});
Nasty.Param.TextPop.push({
namepop_size: Number(Nasty.Parameters['Font Size 10']),
namepop_color: String(Nasty.Parameters['Font Color 10']),
namepop_outlineWidth: Number(Nasty.Parameters['Outline Size 10']),
namepop_outlineColor: String(Nasty.Parameters['Outline Color 10']),
namepop_font: String(Nasty.Parameters['Font Name 10']),
namepop_ital: String(Nasty.Parameters['Font italic? 10']),
namepop_time: Number(Nasty.Parameters['Time 10']),
namepop_offsetx: Number(Nasty.Parameters['Offset_X 10']),
namepop_offsety: Number(Nasty.Parameters['Offset_Y 10'])
});
var Nasty_EvText_gme_charcter_init_alias = Game_Character.prototype.initialize;
Game_Character.prototype.initialize = function() {
Nasty_EvText_gme_charcter_init_alias.call(this);
this.namepop = "";
this.namepop_size = 28;
this.namepop_color = '#ffffff';
this.namepop_outlineColor = 'rgba(0, 0, 0, 0.5)';
this.namepop_outlineWidth = 4;
this.namepop_time = 0;
this.namepop_font = 'GameFont';
this.namepop_ital = false;
this.windowOpacity = 0;
this.namepop_ox = 0;
this.namepop_oy = 0;
this.namepop_width = 0;
this.namepop_height = 0;
this.textpop_flag = false; //Shut off switch
};
Game_Character.prototype.setTextOptions = function(textOption) {
var text = Nasty.Param.TextPop[textOption];
this.namepop_size = text.namepop_size;
this.namepop_color = text.namepop_color;
this.namepop_outlineColor = text.namepop_outlineColor;
this.namepop_outlineWidth = text.namepop_outlineWidth;
this.namepop_time = text.namepop_time;
this.namepop_font = text.namepop_font;
this.namepop_ital = text.namepop_ital;
this.namepop_ox = text.namepop_offsetx;
this.namepop_oy = text.namepop_offsety;
this.textpop_flag = true;
};
var Nasty_evText_chrsprite_init_alias = Sprite_Character.prototype.initialize;
Sprite_Character.prototype.initialize = function(character) {
Nasty_evText_chrsprite_init_alias.call(this, character);
this.char = character;
this.text_timer = 0;
};
var Nasty_sprCharacterTxtPop_update_alias = Sprite_Character.prototype.update;
Sprite_Character.prototype.update = function() {
Nasty_sprCharacterTxtPop_update_alias.call(this);
if (this.text_timer > 0 && this.char.textpop_flag === false){
this.text_timer -=1;
if (this.text_timer <= 0){
this.removeChild(this.namepop_sprite);
this.tmer_rat = undefined; //Reset ratio, just to avoid issues
}
else if (this.text_timer < 60){
this.namepop_sprite.contentsOpacity-= 4;
this.namepop_sprite.opacity -= 4;
}
}
if (this.char.textpop_flag === true){
if (this.namepop === this.char.namepop) return;
this.namepop = this.char.namepop;
this.removeChild(this.namepop_sprite);
this.start_namepop();
this.char.textpop_flag = false; //Release from update
}
};
Sprite_Character.prototype.start_namepop = function(){
if (this.namepop === "") return;
var b_width = (this.namepop.length * (this.char.namepop_size/2) + 24)+this.char.namepop_width;
var b_height = (this.char.namepop_size + 28) + this.char.namepop_height;
var x = (0 - b_width/2) + this.char.namepop_ox;
var y = (0 - b_height - 48) - this.char.namepop_oy;
this.namepop_sprite = new Window_CharacterPop(x,y,b_width,b_height,this.char);
this.namepop_sprite.z = 100;
this.namepop_sprite.opacity = this.char.windowOpacity;
//###Change Font, Font Size, Color, and Time based off Character values##
this.namepop_sprite.contents.textColor = this.char.namepop_color;
this.namepop_sprite.contents.outlineColor = this.char.namepop_outlineColor;
this.namepop_sprite.contents.outlineWidth = this.char.namepop_outlineWidth;
this.namepop_sprite.contents.fontSize = this.char.namepop_size;
this.namepop_sprite.contents.fontFace = this.char.namepop_font;
this.namepop_sprite.contents.fontItalic = this.char.namepop_ital;
this.namepop_sprite.drawTextEx(this.namepop, 0, 0);
this.text_timer = this.char.namepop_time;
this.namepop_time = this.char.namepop_time;
this.namepop_sprite.visible = true;
this.addChild(this.namepop_sprite);
};
//-----------------------------------------------------------------------------
// Window_CharacterPop
//
function Window_CharacterPop() {
this.initialize.apply(this, arguments);
}
Window_CharacterPop.prototype = Object.create(Window_Base.prototype);
Window_CharacterPop.prototype.constructor = Window_CharacterPop;
Window_CharacterPop.prototype.initialize = function(x, y, width, height,character) {
Window_Base.prototype.initialize.call(this, x, y, width, height);
this.character = character;
};
var Nasty_TxtPop_drawTextEx_alias = Window_Base.prototype.drawTextEx;
Window_Base.prototype.drawTextEx = function(text, x, y) {
//Only run for Window_CharacterPop windows
if (this.constructor.name==='Window_CharacterPop'){
if (text) {
var textState = { index: 0, x: x, y: y, left: x };
textState.text = this.convertEscapeCharacters(text);
textState.height = this.calcTextHeight(textState, false);
while (textState.index < textState.text.length) {
this.processCharacter(textState);
}
return textState.x - x;
} else {
return 0;
}
}else {
//All other Windows
return Nasty_TxtPop_drawTextEx_alias.call(this,text, x, y);
}
};
var Nasty_txtpop_standardpadding_alias = Window_Base.prototype.standardPadding;
Window_Base.prototype.standardPadding = function() {
if (this.constructor.name==='Window_CharacterPop'){
return 8;
}else{
return Nasty_txtpop_standardpadding_alias.call(this);
}
};
//=============================================================================
// Game_Interpreter - New Plugin Commands
//=============================================================================
var Nasty_TextPopEvents_change_pluginCommand =
Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
Nasty_TextPopEvents_change_pluginCommand.call(this, command, args);
if (command.toUpperCase() === 'NASTYTEXTPOP') {
var ev_id = args.shift(),
template = args.shift()-1,
time = args.shift(),
textString = (args.join(" "));
char = this.getCharacter_for_Nasty_Text_Pop(ev_id);
char.namepop = textString;
char.namepop_size = Nasty.Param.TextPop[template].namepop_size;
char.namepop_color = Nasty.Param.TextPop[template].namepop_color;
char.namepop_outlineColor = Nasty.Param.TextPop[template].namepop_outlineColor;
char.namepop_outlineWidth = Nasty.Param.TextPop[template].namepop_outlineWidth;
char.namepop_time = time;
char.namepop_font = Nasty.Param.TextPop[template].namepop_font;
if (Nasty.Param.TextPop[template].namepop_ital==='true') char.namepop_ital = true;
char.textpop_flag = true; //Catch in update
}
};
var Nasty_txtpop_reset_text_options_alias = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
Nasty_txtpop_reset_text_options_alias.call(this, command, args);
if (command.toUpperCase() === 'RESETTEXTOPTIONS') {
for (i=0; i<args.length; i++){
char = this.getCharacter_for_Nasty_Text_Pop(args[i]);
char.namepop = "";
char.windowOpacity = 0;
char.namepop_ox = 0;
char.namepop_oy = 0;
char.namepop_width = 0;
char.namepop_height = 0;
char.namepop_ital = false;
}
}
};
Game_Interpreter.prototype.NastyTextPop = function(data){
//Check for data arguments
data.text = data.text || "";
data.id = data.id || 0;
data.template = data.template-1 || 0;
data.windowOpacity = data.windowOpacity || 0;
data.font = data.font || Nasty.Param.TextPop[data.template].namepop_font;
data.fontsize = data.fontsize || Nasty.Param.TextPop[data.template].namepop_size;
data.fontcolor = data.fontcolor || Nasty.Param.TextPop[data.template].namepop_color;
data.outlineColor = data.outlineColor || Nasty.Param.TextPop[data.template].namepop_outlineColor;
data.outlineWidth = data.outlineWidth || Nasty.Param.TextPop[data.template].namepop_outlineWidth;
data.italic = data.italic || Nasty.Param.TextPop[data.template].namepop_ital;
data.time = data.time || Nasty.Param.TextPop[data.template].namepop_time;
data.width = data.width || 0;
data.height = data.height || 0;
data.x = data.x || 0;
data.y = data.y || 0;
//Convert data arguments to Characters
char = this.getCharacter_for_Nasty_Text_Pop(data.id);
char.namepop = data.text;
char.namepop_size = data.fontsize;
char.namepop_color = data.fontcolor;
char.namepop_outlineColor = data.outlineColor;
char.namepop_outlineWidth = data.outlineWidth;
char.windowOpacity = data.windowOpacity;
char.namepop_time = data.time;
char.namepop_ox = data.x;
char.namepop_oy = data.y;
char.namepop_width = data.width;
char.namepop_height = data.height;
if (data.italic===true) char.namepop_ital = true;
char.namepop_font = data.font;
char.textpop_flag = true;
};
Game_Interpreter.prototype.getCharacter_for_Nasty_Text_Pop = function(param){
//Similar to Game_Interpreter.character function just added follower logic.
if ($gameParty.inBattle()) {
return null;
} else if (param == -1) {
return $gamePlayer;
} else if (param < -1) {
return $gamePlayer._followers.follower((Math.abs(param)-2));
} else if (this.isOnCurrentMap()) {
return $gameMap.event(param > 0 ? param : this._eventId);
} else {
return null;
}
};
})(Nasty.Event_Text_Pop);
================================================
FILE: game_resources/js/plugins/Online_Chat.js
================================================
var Imported = Imported || {};
Imported.Online_Chat = true;
(function () {
var Nasty = Nasty || {};
//=============================================================================
// Online Chat
// Version: 1.0.6 - Fix for crashing while in menu
// Version: 1.0.5 - Allows for chat to be retained on map transfer/menu/battle
// Version: 1.0.4 - Add function to enable/disable chat and chat by leader name
//=============================================================================
//=============================================================================
/*:
* @plugindesc Online Chat for Neldersons Online Core
* <Online_Chat>
* @author Nelderson
*
* @param Chat Key Code
* @desc Key code to toggle the chat on/off (Default F1 - 112)
* @default 112
*
* @param Chat with Username or Character Name
* @desc 0=Username 1=Character Name (Leader of party)
* @default 0
*
* @param Input Character limit
* @desc Limit the amount of characters per message
* @default 80
*
* @param Room Name by Map
* @desc Change the room name by map that you are on?
* @default false
*
* @param Recall Message Limit
* @desc Recalls this many messages when switching maps/battles/etc
* @default 20
*
* @param Chat Username Color
* @desc Color of usernames in chat window
* @default #c92cac
*
* @param Chat Text Color
* @desc Color of chat text in chat window
* @default #000000
*
* @param Chat Text Window Width
* @desc Chat Window width
* @default 800
*
* @param Chat Text Window Height
* @desc Chat Window Height
* @default 500
*
* @param Chat Text Window Offset X
* @desc Offset X Poisition of Chat Text Window from CENTER
* @default 0
*
* @param Chat Text Window Offset Y
* @desc Offset Y Poisition of Chat Text Window from CENTER
* @default 0
*
* @param Chat Text Font
* @desc Font for Chat Text (Defaults to game default)
* @default
*
* @param Chat Text Font Size
* @desc Font size for Chat Text
* @default 15
*
* @param Chat Text Background Color
* @desc Background color and transparency for Chat Window
* @default rgba(255,255,255,0.7)
*
* @param Chat Text Background Picture
* @desc Background Pic from img/pictures folder instead of Background Color
* @default
*
* @param Chat Input Window Width
* @desc Chat Input Window width
* @default 600
*
* @param Chat Input Window Height
* @desc Chat Input Window Height
* @default 40
*
* @param Chat Input Window Offset X
* @desc Offset X Poisition of Chat Input Window from CENTER
* @default 0
*
* @param Chat Input Window Offset Y
* @desc Offset Y Poisition of Chat Input Window from CENTER
* @default 564
*
* @param Input Text Font
* @desc Font for Input Text (Defaults to game default)
* @default
*
* @param Input Text Font Size
* @desc Font size for Input Text
* @default 15
*
* @param Input Text Background Color
* @desc Background color and transparency for Input Window
* @default rgba(255,255,255,0.7)
*
* @param Input Text Background Picture
* @desc Background Pic from img/pictures folder instead of Background Color
* @default
*
* @help
* ============================================================================
* Introduction and Instructions
* ============================================================================
* This plugin allows you to chat with other players.
*
* There are two ways to access the chat windows. Either by plugin
* command or the Key Code from the parameters(Default F1).
*
* The only thing that is overwritten are the defaults for the SPACEBAR
* and Z key within the Input Keymapper so that they will not interfere
* with typing in the chat input window
*
* =====================
* ===Plugin Commands===
* =====================
*
* ToggleChat - Turns Chat Windows On/Off
* SendChatMessage - Sends the message in the chat input window.
* EnableChat - Enables chat to be opened
* DisableChat - Disables chat to be opened
*
*/
//=============================================================================
var socket = null;
var chatHistory = [];
Nasty.Parameters = $plugins.filter(function(p)
{ return p.description.contains('<Online_Chat>');})[0].parameters;
//Chat text window
var textWinWidth = Nasty.Parameters['Chat Text Window Width'];
var textWinHeight = Nasty.Parameters['Chat Text Window Height'];
var textWinOffsetX = Nasty.Parameters['Chat Text Window Offset X'];
var textWinOffsetY = Nasty.Parameters['Chat Text Window Offset Y'];
var textWinFont = Nasty.Parameters['Chat Text Font'];
var textWinFontSize = Nasty.Parameters['Chat Text Font Size'];
var textWinBack = Nasty.Parameters['Chat Text Background Color'];
var textWinBackPic = Nasty.Parameters['Chat Text Background Picture'];
//Chat input window
var inputWinWidth = Nasty.Parameters['Chat Input Window Width'];
var inputWinHeight = Nasty.Parameters['Chat Input Window Height'];
var inputWinOffsetX = Nasty.Parameters['Chat Input Window Offset X'];
var inputWinOffsetY = Nasty.Parameters['Chat Input Window Offset Y'];
var inputWinFont = Nasty.Parameters['Input Text Font'];
var inputWinFontSize = Nasty.Parameters['Input Text Font Size'];
var inputWinBack = Nasty.Parameters['Input Text Background Color'];
var inputWinBackPic = Nasty.Parameters['Input Text Background Picture'];
var inputCharLimit = Nasty.Parameters['Input Character limit'];
var chatKeyCode = Nasty.Parameters['Chat Key Code'];
var chatUserColor = Nasty.Parameters['Chat Username Color'];
var chatTextColor = Nasty.Parameters['Chat Text Color'];
var roomMapNameFlag = Nasty.Parameters['Room Name by Map'];
var NetPlayerChatNameType = Number(Nasty.Parameters['Chat with Username or Character Name']);
var recallMessageLimit = Number(Nasty.Parameters['Recall Message Limit']);
var networkName = '';
var OnlineMV_ChatSystem_SocketConn_Alias = Game_Network.prototype.connectSocketsAfterLogin;
Game_Network.prototype.connectSocketsAfterLogin = function(){
OnlineMV_ChatSystem_SocketConn_Alias.call(this);
$gameNetwork.connectSocket('chat','/chat',false);
socket = $gameNetwork._socket.chat;
Nasty.chatEnabled = true;
socket.on('MyID',function(data){
networkName = data.name;
});
socket.on('messageServer', function(data){
var chat = document.getElementById('txtarea');
var message = document.createElement('div');
var user = document.createElement('span');
var chatText = document.createElement('span');
//Combine user/text spans to div container
user.style.color = chatUserColor;
chatText.style.color = chatTextColor;
user.textContent = data.id+ ': ';
chatText.textContent = data.message;
if (message){
message.appendChild(user);
message.appendChild(chatText);
}
chatHistory.push([user, chatText]);
//Append to chat text div
if (chat) {
chat.appendChild(message);
chat.scrollTop = chat.scrollHeight;
}
});
};
//=============================================================================
// GAME CHAT code
//=============================================================================
var OnlineChat_createDisplayObj_Scene_Map = Scene_Map.prototype.createDisplayObjects;
Scene_Map.prototype.createDisplayObjects = function() {
OnlineChat_createDisplayObj_Scene_Map.call(this);
this.createChatDOMElements();
this.appendChatHistory();
};
Scene_Map.prototype.appendChatHistory = function(){
var diff = chatHistory.length - recallMessageLimit;
if (diff>0) chatHistory.splice(0,diff);
var chat = document.getElementById('txtarea');
for (var i=0;i<chatHistory.length;i++){
var message = document.createElement('div');
message.appendChild(chatHistory[i][0]);
message.appendChild(chatHistory[i][1]);
chat.appendChild(message);
}
};
Scene_Map.prototype.createChatDOMElements = function(){
//Chat Bar for Inputing messages
this.chatinput = document.createElement('INPUT');
this.chatinput.id = 'chatInput';
this.chatinput.maxLength = inputCharLimit;
this.chatinput.style.fontSize = inputWinFont + 'px';
this.chatinput.style.fontStyle = inputWinFont;
this.chatinput.style.color = '#ffffff';
this.chatinput.style.fontStyle = '';
this.chatinput.style.position = 'absolute';
this.chatinput.style.textIndent = '15px';
this.chatinput.style.zIndex = 100;
this.chatinput.placeholder = 'Insert Text Here';
this.chatinput.style.color = '#000000';
this.chatinput.style.border = 'none';
this.chatinput.style.visibility = 'hidden';
if (inputWinBackPic===''){
this.chatinput.style.background = inputWinBack;
}else{
this.chatinput.style.backgroundImage = "url('img/pictures/"+inputWinBackPic+".png')";
}
//Chat Message area
this.txtarea = document.createElement('div');
this.txtarea.id = 'txtarea';
this.txtarea.style.padding = '15px';
this.txtarea.style.fontSize = textWinFontSize + 'px';
this.txtarea.style.fontStyle = textWinFont;
this.txtarea.style.position = 'absolute';
this.txtarea.style.overflowY = 'auto';
this.txtarea.style.width = textWinWidth + 'px';
this.txtarea.style.height = textWinHeight + 'px';
this.txtarea.style.zIndex = 99;
this.txtarea.style.visibility = 'hidden';
if (textWinBackPic===''){
this.txtarea.style.background = textWinBack;
}else{
this.txtarea.style.backgroundImage = "url('img/pictures/"+textWinBackPic+".png')";
}
//Add and adjust both DOM elements
document.body.appendChild(this.txtarea);
document.body.appendChild(this.chatinput);
//--Mobile fix for input--
$("#chatInput").tap(function(){$("#chatInput").focus();});
//-------------------------
Graphics._centerElement(this.chatinput);
Graphics._centerElement(this.txtarea);
this.chatinput.style.width = inputWinWidth +'px';
this.chatinput.style.height = inputWinHeight + 'px';
this.chatinput.style.top = inputWinOffsetY +'px';
this.chatinput.style.left = inputWinOffsetX +'px';
this.txtarea.style.left = textWinOffsetX + 'px';
this.txtarea.style.top = textWinOffsetY + 'px';
var that = this;
$("#chatInput").keypress(function(e){
if (e.which == 13) { //enter
that.sendChatMessage();
}
});
};
var Online_Chat_SceneMap_isMenuCalled_alias = Scene_Map.prototype.isMenuCalled;
Scene_Map.prototype.isMenuCalled = function() {
if (document.activeElement===document.getElementById('chatInput')) return false;
return Online_Chat_SceneMap_isMenuCalled_alias.call(this);
};
var Online_Chat_SceneMap_ProcessTouch_alias = Scene_Map.prototype.processMapTouch;
Scene_Map.prototype.processMapTouch = function() {
if (document.activeElement!==document.getElementById('chatInput')){
Online_Chat_SceneMap_ProcessTouch_alias.call(this);
}
};
var Chat_Online_sceneMap_updtSceneAlias = Scene_Map.prototype.updateScene;
Scene_Map.prototype.updateScene = function() {
Chat_Online_sceneMap_updtSceneAlias.call(this);
if (!SceneManager.isSceneChanging()) {
this.updateChat();
}
};
Scene_Map.prototype.updateChat = function(){
if (document.activeElement===document.getElementById('chatInput')){
if (Input.isTriggered('ok')){
this.sendChatMessage();
}
}
//Toggle Chat Windows On/Off
if (Input.isTriggered('chat')){
this.toggleChat();
}
};
Scene_Map.prototype.sendChatMessage = function(){
if (NetPlayerChatNameType===1) networkName=$gameParty.leader()._name;
var value = document.getElementById('chatInput').value;
value = value.trim();
if (value==='') return;
//Emit message to server
socket.emit('clientMessage',{
id: networkName,
message: value
});
document.getElementById('chatInput').value = '';
};
Scene_Map.prototype.toggleChat = function(){
if (!Nasty.chatEnabled) {
document.getElementById('txtarea').style.visibility = 'hidden';
document.getElementById('chatInput').style.visibility = 'hidden';
return;
}
if (document.getElementById('txtarea').style.visibility ==='hidden'){
document.getElementById('txtarea').style.visibility = 'visible';
document.getElementById('chatInput').style.visibility = 'visible';
$("#chatInput").focus();
}else{
document.getElementById('txtarea').style.visibility = 'hidden';
document.getElementById('chatInput').style.visibility = 'hidden';
}
};
var NastySceneMapChat_Terminate = Scene_Map.prototype.terminate;
Scene_Map.prototype.terminate = function() {
NastySceneMapChat_Terminate.call(this);
document.body.removeChild(this.txtarea);
document.body.removeChild(this.chatinput);
};
var OnlineChat_gamePlayer_canMoveAlias = Game_Player.prototype.canMove;
Game_Player.prototype.canMove = function() {
if (document.activeElement===document.getElementById('chatInput')){
return false;
}
return OnlineChat_gamePlayer_canMoveAlias.call(this);
};
var Nel_OnlineChat_pluginCommands_alias = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
Nel_OnlineChat_pluginCommands_alias.call(this, command, args);
if (command.toUpperCase() === 'TOGGLECHAT'){
if (SceneManager._scene instanceof Scene_Map){
SceneManager._scene.toggleChat();
}
}
if (command.toUpperCase() === 'SENDCHATMESSAGE'){
if (SceneManager._scene instanceof Scene_Map){
SceneManager._scene.sendChatMessage();
}
}
if (command.toUpperCase() === 'ENABLECHAT'){
Nasty.chatEnabled = true;
}
if (command.toUpperCase() === 'DISABLECHAT'){
Nasty.chatEnabled = false;
if (SceneManager._scene instanceof Scene_Map){
SceneManager._scene.toggleChat();
}
}
};
//Re-Map Input Keys
Input.keyMapper[chatKeyCode] = 'chat';
Input.keyMapper['90'] = 'none'; // Z
Input.keyMapper['32'] = 'none'; // SpaceBar
})();
================================================
FILE: game_resources/js/plugins/Online_CloudSave.js
================================================
/*
Online Cloud Save v.0.1.1
Take data from one source and be able to load it on other devices
Sign in > Check the Database > Have data? > Load from database
No > New Game
*/
(function() {
var CloudSave_StorageManager_save_alias = StorageManager.save;
StorageManager.save = function(savefileId, json) {
if (savefileId>0){
var data = LZString.compressToBase64(json);
$.post($gameNetwork._serverURL+'/cloudsave/savetocloud', {savedata: data});
}
};
//Overwrite Save Command in Menu
Scene_Menu.prototype.commandSave = function() {
DataManager.saveGameWithoutRescue(2);
this._commandWindow.processCancel();
};
DataManager.loadGameWithoutRescue = function(savefileId) {
if (savefileId >0){
var globalInfo = this.loadGlobalInfo();
var json = StorageManager.load(savefileId);
return true;
}
};
StorageManager.load = function(savefileId) {
if (savefileId>0){
$.get($gameNetwork._serverURL+'/cloudsave/loadfromcloud', function(data){
if (data==="No account") return; //Loads new game if no data
var json = LZString.decompressFromBase64(data);
DataManager.createGameObjects();
DataManager.extractSaveContents(JsonEx.parse(json));
}).fail(function(){
window.alert("Cloudsave Failed!");
});
}
};
var CloudSave_GameNetwork_ConnectafterLogin = Game_Network.prototype.connectSocketsAfterLogin;
Game_Network.prototype.connectSocketsAfterLogin = function(socket) {
CloudSave_GameNetwork_ConnectafterLogin.call(this,socket);
//Set header so that token is passed correctly to the server
$.ajaxSetup({
headers: {
'x-access-token': $gameNetwork._token
}
});
DataManager.loadGameWithoutRescue(2);
};
})();
================================================
FILE: game_resources/js/plugins/Online_GlobalVars.js
================================================
//=============================================================================
// Online Global Variables and Switches
// Version: 0.2 - Add parameters for non global switches and variables
// Version: 0.1 - Send switch and variable data to all clients connected
//=============================================================================
//=============================================================================
/*:
* @plugindesc Send switch and variable data to others.
*<Online_GlobalVars>
* @author Nelderson
*
* @param Global Switch Threshold
* @desc Any switch below this number will be global.
* @default 100
*
* @param Global Variable Threshold
* @desc Any variable below this number will be global.
* @default 100
*
* @help
* ============================================================================
* Introduction and Instructions
* ============================================================================
* This plugin allows you to send variable and switch data to others in
* the same server/room.
*
* There are 2 basic configurations:
*
* Global Switch Threshold and Global Variable Threshold
*
* These allow you to define where global variables/switches
* end and where normal variables/switches happen
*
* Ex. Global Switch Threshold of 100
*
* Anything below and including 100 is a global switch,
* and anything above is a normal switch
*
*/
//=============================================================================
(function () {
var GlobalVar_PParameters = $plugins.filter(function(p)
{ return p.description.contains('<Online_GlobalVars>');})[0].parameters;
var switchThreshold = Number(GlobalVar_PParameters['Global Switch Threshold']);
var variableThreshold = Number(GlobalVar_PParameters['Global Variable Threshold']);
var socket=null;
var OnlineMV_GlobalVars_SocketConn_Alias = Game_Network.prototype.connectSocketsAfterLogin;
Game_Network.prototype.connectSocketsAfterLogin = function(){
OnlineMV_GlobalVars_SocketConn_Alias.call(this);
$gameNetwork.connectSocket('globalvar','/globalvar');
//Emitters and Listeners
//emit/broadcast and on
socket = $gameNetwork._socket.globalvar;
socket.on('receivedSwitch', function(data){
//Do something with received data
$gameSwitches.setNetworkValue(data.switch, data.value);
});
socket.on('receivedVariable', function(data){
//Do something with received data
$gameVariables.setNetworkValue(data.variable, data.value);
});
};
var Online_GlobalSwitch_setVal = Game_Switches.prototype.setValue;
Game_Switches.prototype.setValue = function(switchId, value) {
if (switchId>0 && switchId<$dataSystem.switches.length && switchId<=switchThreshold) {
//Send data to server!
socket.emit('switchDatatoServer',{
switch: switchId,
value: value
});
}
Online_GlobalSwitch_setVal.call(this,switchId, value);
};
Game_Switches.prototype.setNetworkValue = function(switchId, value) {
if (switchId > 0 && switchId < $dataSystem.switches.length) {
this._data[switchId] = value;
this.onChange();
}
};
var Online_GlobalVariable_setVal = Game_Variables.prototype.setValue;
Game_Variables.prototype.setValue = function(variableId, value) {
if (variableId>0 && variableId<$dataSystem.variables.length && variableId<=variableThreshold) {
socket.emit('variableDatatoServer',{
variable: variableId,
value: value
});
}
Online_GlobalVariable_setVal.call(this, variableId, value);
};
Game_Variables.prototype.setNetworkValue = function(variableId, value) {
if (variableId > 0 && variableId < $dataSystem.variables.length) {
if (typeof value === 'number') {
value = Math.floor(value);
}
this._data[variableId] = value;
this.onChange();
}
};
})();
================================================
FILE: game_resources/js/plugins/Online_Login_Core.js
================================================
var Imported = Imported || {};
Imported.Online_Login_Core = true;
(function () {
var Nasty = Nasty || {};
//=============================================================================
// Online Login Core
// Version: 1.1.6 - Added logic to use localstorage to auto login
// Version: 1.1.5 - Added Password Reset Logic
// Version: 1.1.4 - Added event switches for when users login multiple times
// Version: 1.1.3
//=============================================================================
//=============================================================================
/*:
* @plugindesc Login window for Neldersons Online Core
*<Online_Login_Core>
* @author Nelderson and SirMcPotato/Vinxce
*
* @param Force Login on Startup
* @desc Make the title screen into a login screen
* @default true
*
* @param socket.io connection
* @desc Automatically connects to socket once signed in.
* @default true
*
* @param Switch on First Shutdown
* @desc Original user that is logged in will have this switch flipped
* @default 1
*
* @param Switch on Second Shutdown
* @desc Second user that is logged in will have this switch flipped
* @default 2
*
* @help
* ============================================================================
* Introduction and Instructions
* ============================================================================
* You can use the login window in two ways.
*
* 1. Set Force login on Startup parameter to true:
* This will force the login screen on startup.
*
* 2. Set Force login on Startup parameter to false:
* You can use this plugin command to pop up the
* login window at any point in your game:
*
* Online_Login
*
* The socket.io connection parameter refers to if you
* want to automatically upgrade to sockets after login.
*
*/
//=============================================================================
Nasty.Parameters = $plugins.filter(function(p)
{ return p.description.contains('<Online_Login_Core>');})[0].parameters;
var Nel_online_login_core_plugincomm_alias = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
Nel_online_login_core_plugincomm_alias.call(this, command, args);
if (command.toUpperCase() === 'ONLINE_LOGIN') {
if ($gameNetwork._token===0){
SceneManager.goto(MMO_Scene_Title);
}
}
};
//----------------------------------------------------------------------------
// MMO_Scene_Title
//
// Title scene including login form.
//----------------------------------------------------------------------------
function MMO_Scene_Title() {
this.initialize.apply(this, arguments);
}
MMO_Scene_Title.prototype = Object.create(Scene_Base.prototype);
MMO_Scene_Title.prototype.constructor = MMO_Scene_Title;
MMO_Scene_Title.prototype.initialize = function() {
Scene_Base.prototype.initialize.call(this);
};
MMO_Scene_Title.prototype.reBindInput = function() {
Input.initialize();
};
MMO_Scene_Title.prototype.create = function() {
Scene_Base.prototype.create.call(this);
this.createBackground();
};
MMO_Scene_Title.prototype.start = function() {
Scene_Base.prototype.start.call(this);
var token = localStorage.getItem('token');
var that = this
SceneManager.clearStack();
this.playTitleMusic();
this.startFadeIn(this.fadeSpeed(), false);
if (token) {
//Need to veriy token
$.get($gameNetwork._serverURL+'/verify-token', {token: token},
function(data){
that.createLogoutContinueForm(data.token.name, token);
})
.fail(function(){
that.createLoginForm();
});
}
else{
this.createLoginForm();
}
};
MMO_Scene_Title.prototype.update = function() {
Scene_Base.prototype.update.call(this);
};
MMO_Scene_Title.prototype.isBusy = function() {
return Scene_Base.prototype.isBusy.call(this);
};
MMO_Scene_Title.prototype.terminate = function() {
Scene_Base.prototype.terminate.call(this);
SceneManager.snapForBackground();
};
MMO_Scene_Title.prototype.createRegistrationForm = function() {
$("#ErrorPrinter").html(
'<div id="RegisterForm" class="panel panel-primary" style="width:'+(Graphics.boxWidth - (Graphics.boxWidth / 3))+'px">'+
'<div class="panel-heading">Register</div>'+
'<div class="panel-body">'+
'<div id="loginErrBox"></div>'+
'<div class="form-group">'+
'<input type="text" id="regUsername" name="username" placeholder="Enter Username" class="form-control"/>'+
'</div>'+
'<div class="form-group">'+
'<input type="text" name="email" id="regEmail" placeholder="Email Address" class="form-control"/>'+
'</div>'+
'<div class="form-group">'+
'<input type="password" name="password" id="regPassword" placeholder="Password" class="form-control"/>'+
'</div>'+
'<button id="btnSubmit"type="submit" class="btn btn-default">Submit</button>'+
'<button id ="btnCancel" type="button" class="btn btn-primary">Cancel</button>'+
'</div>'+
'</div>');
var that = this;
$(".form-control").keypress(function(e){
if (e.which == 13) { //enter
that.registerAttempt();
}
});
$("#regUsername").tap(function(){$("#regUsername").focus();});
$("#regEmail").tap(function(){$("#regEmail").focus();});
$("#regPassword").tap(function(){$("#regPassword").focus();});
$("#btnSubmit").bind("click touchstart",function(){that.registerAttempt();});
$("#btnCancel").bind("click touchstart",function(){that.createLoginForm();});
};
// Testing purpose, need to be rewritten into something more modulable,
// maybe using template file?
// Can be wise to work on a set of sprite-based form inputs for
// a better visual integration.
MMO_Scene_Title.prototype.createLoginForm = function() {
$("#ErrorPrinter").html(
'<div id="LoginForm" class="panel panel-primary" style="width:'+(Graphics.boxWidth - (Graphics.boxWidth / 3))+'px">'+
'<div class="panel-heading">Login</div>'+
'<div class="panel-body">'+
'<div id="loginErrBox"></div>'+
'<div class="input-group">'+
'<span class="input-group-addon" id="username-addon"><i class="fa fa-user"></i></span>'+
'<input type="text" class="form-control login-input" id="inputUsername" placeholder="Username" aria-describedby="username-addon">'+
'</div><br>'+
'<div class="input-group">'+
'<span class="input-group-addon" id="password-addon"><i class="fa fa-lock"></i></span>'+
'<input type="password" class="form-control login-input" id="inputPassword" placeholder="Password" aria-describedby="password-addon">'+
'</div><br>'+
'<button id="btnConnect" class="btn btn-primary">Connect</button>'+
'<button id="btnRegister" class="btn btn-default">Register</button>'+
'<button id="btnForgotPassword" class="btn btn-link btn-sm">Forgot Password?</button>'+
'</div>'+
'</div>');
//Bind commands
var that = this;
$(".login-input").keypress(function(e){
if (e.which == 13) { //enter
that.connectAttempt();
}
});
$("#inputUsername").tap(function(){$("#inputUsername").focus();});
$("#inputPassword").tap(function(){$("#inputPassword").focus();});
$("#btnConnect").bind("click touchstart",function(){that.connectAttempt();});
$("#btnRegister").bind("click touchstart",function(){that.createRegistrationForm();});
$("#btnForgotPassword").bind("click touchstart",function(){that.createLostPasswordForm();});
$("#inputUsername").focus();
};
MMO_Scene_Title.prototype.createActivationForm = function() {
$("#ErrorPrinter").html(
'<div id="ActivationForm" class="panel panel-primary" style="width:'+(Graphics.boxWidth - (Graphics.boxWidth / 3))+'px">'+
'<div class="panel-heading">Activation</div>'+
'<div class="panel-body">'+
'<div id="loginErrBox"></div>'+
'<div class="input-group">'+
'</div><br>'+
'<button id="btnActLogin" class="btn btn-primary">Login</button>'+
'</div>'+
'</div>');
//Bind commands
var that = this;
$(".login-input").keypress(function(e){
if (e.which == 13) { //enter
that.createLoginForm();
}
});
$("#btnActLogin").bind("click touchstart",function(){that.createLoginForm();});
};
MMO_Scene_Title.prototype.createLogoutContinueForm = function(name, token) {
$("#ErrorPrinter").html(
`<div id="ActivationForm" class="panel panel-primary" style="width: ${(Graphics.boxWidth - (Graphics.boxWidth / 3))}px">
<div class="panel-heading">Welcome ${name}</div>
<div class="panel-body">
<div id="loginErrBox"></div>
<div class="input-group">
</div><br>
<button id="btnContinue" class="btn btn-primary">Continue</button>
<button id="btnLogout" class="btn btn-default">Log Out</button>
</div>
</div>`);
//Bind commands
var that = this;
$("#btnLogout").bind("click touchstart",function(){
localStorage.removeItem('token');
that.createLoginForm();
});
$("#btnContinue").bind("click touchstart",function(){
$gameNetwork._token = token;
var ioFlag = String(Nasty.Parameters['socket.io connection']);
$("#ErrorPrinter").fadeOut({duration: 1000}).html("");
if (ioFlag==='true'){
$gameNetwork.connectSocket('main','/');
$gameNetwork._socket.main.on('firstShutDown',function(data){
$gameSwitches.setValue(Number(Nasty.Parameters['Switch on First Shutdown']),true);
});
$gameNetwork._socket.main.on('secondShutDown',function(data){
$gameSwitches.setValue(Number(Nasty.Parameters['Switch on Second Shutdown']),true);
});
}
$gameNetwork.connectSocketsAfterLogin();
that.fadeOutAll();
SceneManager.goto(Scene_Map);
return that.displayInfo("Ok : ");
});
};
MMO_Scene_Title.prototype.displayError = function(msg) {
$("#loginErrBox").html('<div class="alert alert-danger fade in">'+msg+'</div>');
};
MMO_Scene_Title.prototype.displayInfo = function(msg) {
$("#loginErrBox").html('<div class="alert alert-info fade in">'+msg+'</div>');
};
MMO_Scene_Title.prototype.displaySuccess = function(msg) {
$("#loginErrBox").html('<div class="alert alert-success fade in">'+msg+'</div>');
};
MMO_Scene_Title.prototype.createLostPasswordForm = function() {
$("#ErrorPrinter").html(
'<div id="LostPasswordFrom" class="panel panel-primary" style="width:'+(Graphics.boxWidth - (Graphics.boxWidth / 3))+'px">'+
'<div class="panel-heading">Lost Password - Enter Email</div>'+
'<div class="panel-body">'+
'<div id="loginErrBox"></div>'+
'<div class="form-group">'+
'<input type="text" name="email" id="inputEmailLP" placeholder="Email Address" class="form-control"/>'+
'</div>'+
'<button id="btnSubmitLP"type="submit" class="btn btn-primary">Submit</button>'+
'<button id ="btnCancelLP" type="button" class="btn btn-default">Cancel</button>'+
'</div>'+
'</div>');
var that = this;
$(".form-control").keypress(function(e){
if (e.which == 13) { //enter
that.lostPasswordRequest();
}
});
$("#inputEmailLP").tap(function(){$("#inputEmailLP").focus();});
$("#btnSubmitLP").bind("click touchstart",function(){that.lostPasswordRequest();});
$("#btnCancelLP").bind("click touchstart",function(){that.createLoginForm();});
$("#inputEmailLP").focus();
};
MMO_Scene_Title.prototype.createResetPasswordForm = function() {
$("#ErrorPrinter").html(
'<div id="PasswordResetForm" class="panel panel-primary" style="width:'+(Graphics.boxWidth - (Graphics.boxWidth / 3))+'px">'+
'<div class="panel-heading">Password Reset</div>'+
'<div class="panel-body">'+
'<div id="loginErrBox"></div>'+
'<div class="form-group">'+
'<input type="password" name="password" id="inputPasswordCP" placeholder="New Password" class="form-control"/>'+
'</div>'+
'<div class="form-group">'+
'<input type="password" name="password" id="inputPasswordConfirmCP" placeholder="Confirm Password" class="form-control"/>'+
'</div>'+
'<button id="btnChangeCP"type="submit" class="btn btn-primary">Change</button>'+
'<button id ="btnCancelCP" type="button" class="btn btn-default">Cancel</button>'+
'</div>'+
'</div>');
var that = this;
$(".form-control").keypress(function(e){
if (e.which == 13) { //enter
that.changePasswordRequest();
}
});
$("#inputPasswordCP").tap(function(){$("#inputEmailLP").focus();});
$("#inputPasswordConfirmCP").tap(function(){$("#inputEmailLP").focus();});
$("#btnChangeCP").bind("click touchstart",function(){that.changePasswordRequest();});
$("#btnCancelCP").bind("click touchstart",function(){that.createLoginForm();});
$("#inputPasswordCP").focus();
};
MMO_Scene_Title.prototype.changePasswordRequest = function(){
var that = this;
var pass1 = $("#inputPasswordCP").val();
var pass2 = $("#inputPasswordConfirmCP").val();
if (pass1.length === 0)
return this.displayError("You must provide a new password!");
if (pass2.length === 0)
return this.displayError("You must confirm your password!");
if (pass1!==pass2)
return this.displayError("Passwords do not match!");
this.displayInfo('Connecting <i class="fa fa-spin fa-spinner"></i>');
shapwd = CryptoJS.SHA1(pass1+$gameNetwork._firstHash).toString(CryptoJS.enc.Hex);
$.post($gameNetwork._serverURL+'/resetpassword', {
password: shapwd,
tempHash: $gameSystem._tempPasswordHash,
tempName: $gameSystem._tempPasswordName
}).done(function (data) {
if (data.err) return that.displayError("Error : "+data.err);
that.createLoginForm();
that.displaySuccess("Password Changed Successfully");
});
};
MMO_Scene_Title.prototype.lostPasswordRequest = function(){
var that = this;
var email = $("#inputEmailLP").val();
if (email.length === 0)
return this.displayError("You must provide a username!");
this.displayInfo('Connecting <i class="fa fa-spin fa-spinner"></i>');
$.post($gameNetwork._serverURL+'/lostpassword', {
email: email,
}).done(function (data) {
if (data.err) return that.displayError("Error : "+data.err);
that.createLoginForm();
that.displayInfo("Check email for temporary password");
});
};
MMO_Scene_Title.prototype.connectAttempt = function(){
var that = this;
var username = $("#inputUsername").val();
var password = $("#inputPassword").val();
if (username.length === 0)
return this.displayError("You must provide a username!");
if (password.length === 0)
return this.displayError("You must provide a password!");
shapwd = CryptoJS.SHA1(password+$gameNetwork._firstHash).toString(CryptoJS.enc.Hex);
this.displayInfo('Connecting <i class="fa fa-spin fa-spinner"></i>');
$.post($gameNetwork._serverURL+'/login', {
username: username,
password: shapwd
}).done(function (data) {
if (data.err)
return that.displayError("Error : "+data.err);
if (data.temp){
//Make Password reset form
$gameSystem._tempPasswordName = data.name;
$gameSystem._tempPasswordHash = data.temp;
that.createResetPasswordForm();
}
if (data.token) {
$gameNetwork._token = data.token;
localStorage.setItem('token', data.token);
var ioFlag = String(Nasty.Parameters['socket.io connection']);
$("#ErrorPrinter").fadeOut({duration: 1000}).html("");
if (ioFlag==='true'){
$gameNetwork.connectSocket('main','/');
$gameNetwork._socket.main.on('firstShutDown',function(data){
$gameSwitches.setValue(Number(Nasty.Parameters['Switch on First Shutdown']),true);
});
$gameNetwork._socket.main.on('secondShutDown',function(data){
$gameSwitches.setValue(Number(Nasty.Parameters['Switch on Second Shutdown']),true);
});
}
$gameNetwork.connectSocketsAfterLogin();
that.fadeOutAll();
SceneManager.goto(Scene_Map);
return that.displayInfo("Ok : "+data.msg);
}
});
};
MMO_Scene_Title.prototype.registerAttempt = function(){
var that = this;
var username = $("#regUsername").val();
var password = $("#regPassword").val();
var email = $("#regEmail").val();
if (username.length === 0) return this.displayError("You must provide a username!");
if (password.length === 0) return this.displayError("You must provide a password!");
if (email.length === 0) return this.displayError("You must provide a valid Email!");
this.displayInfo('Connecting <i class="fa fa-spin fa-spinner"></i>');
//POST FOR REGISTER
$.post($gameNetwork._serverURL + '/register', {
username: username,
password: password,
email: email
}).done(function (result) {
var data = result.pageData;
if (data.err)
return that.displayError("Error : "+data.err);
if (data.msg) {
that.createActivationForm();
that.displayInfo("Check your email for the activation link!");
}
});
};
MMO_Scene_Title.prototype.createBackground = function() {
var startupFlag = String(Nasty.Parameters['Force Login on Startup']);
if (startupFlag==='true'){
this._backSprite1 = new Sprite(ImageManager.loadTitle1($dataSystem.title1Name));
this._backSprite2 = new Sprite(ImageManager.loadTitle2($dataSystem.title2Name));
this.addChild(this._backSprite1);
this.addChild(this._backSprite2);
this.centerSprite(this._backSprite1);
this.centerSprite(this._backSprite2);
this.createForeground();
}else{
this._backgroundSprite = new Sprite();
this._backgroundSprite.bitmap = SceneManager.backgroundBitmap();
this.addChild(this._backgroundSprite);
}
};
MMO_Scene_Title.prototype.createForeground = function() {
this._gameTitleSprite = new Sprite(new Bitmap(Graphics.width, Graphics.height));
this.addChild(this._gameTitleSprite);
if ($dataSystem.optDrawTitle) {
this.drawGameTitle();
}
};
MMO_Scene_Title.prototype.drawGameTitle = function() {
var x = 20;
var y = Graphics.height / 4;
var maxWidth = Graphics.width - x * 2;
var text = $dataSystem.gameTitle;
this._gameTitleSprite.bitmap.outlineColor = 'black';
this._gameTitleSprite.bitmap.outlineWidth = 8;
this._gameTitleSprite.bitmap.fontSize = 72;
this._gameTitleSprite.bitmap.drawText(text, x, y, maxWidth, 48, 'center');
};
MMO_Scene_Title.prototype.centerSprite = function(sprite) {
sprite.x = Graphics.width / 2;
sprite.y = Graphics.height / 2;
sprite.anchor.x = 0.5;
sprite.anchor.y = 0.5;
};
MMO_Scene_Title.prototype.playTitleMusic = function() {
AudioManager.playBgm($dataSystem.titleBgm);
AudioManager.stopBgs();
AudioManager.stopMe();
};
//----------------------------------------------------------------------------
//
// Override of Scene_Boot.start, for calling our own Scene_Title!
//
var Nel__SceneBase_Boot_alias_MMO_Login = Scene_Boot.prototype.start;
Scene_Boot.prototype.start = function() {
var startupFlag = String(Nasty.Parameters['Force Login on Startup']);
if (startupFlag==='false'){
Nel__SceneBase_Boot_alias_MMO_Login.call(this);
}
else{
Scene_Base.prototype.start.call(this);
SoundManager.preloadImportantSounds();
if (DataManager.isBattleTest()) {
DataManager.setupBattleTest();
SceneManager.goto(Scene_Battle);
} else if (DataManager.isEventTest()) {
DataManager.setupEventTest();
SceneManager.goto(Scene_Map);
} else {
this.checkPlayerLocation();
DataManager.setupNewGame();
SceneManager.goto(MMO_Scene_Title);
}
this.updateDocumentTitle();
}
};
//-----------------------------------------------------------------------------
//
// Overriding 'Input._onKeyDown' to pass 'event' as parameter
// to 'Input._shouldPreventDefault'
//
Input._onKeyDown = function(event) {
if (this._shouldPreventDefault(event)) {
event.preventDefault();
}
if (event.keyCode === 144) { // Numlock
this.clear();
}
var buttonName = this.keyMapper[event.keyCode];
if (buttonName) {
this._currentState[buttonName] = true;
}
};
//-----------------------------------------------------------------------------
//
// Overriding Input._shouldPreventDefault to allow the use of the 'backspace key'
// in input forms.
//
Input._shouldPreventDefault = function(e) {
switch (e.keyCode) {
case 8: // backspace
if ($(e.target).is("input, textarea"))
break;
case 33: // pageup
case 34: // pagedown
case 37: // left arrow
case 38: // up arrow
case 39: // right arrow
case 40: // down arrow
return true;
}
return false;
};
})();
================================================
FILE: game_resources/js/plugins/Online_Main_Core.js
================================================
var Imported = Imported || {};
Imported.Online_Main_Core = true;
//=============================================================================
// Online Main Core
// Version: 1.1.1
//=============================================================================
//=============================================================================
/*:
* @plugindesc Connect to a server with Socket.io!
*<Online_Main_Core>
* @author Nelderson
*
* @param Server URL
* @desc API/Socket.io server location
* @default http://localhost:8000
*
* @param First Hash
* @desc Same as the server firstHash config
* @default d28cb767c4272d8ab91000283c67747cb2ef7cd1
*
* @help
* ============================================================================
* Introduction and Instructions
* ============================================================================
* This entire core just points and connects to your api/sockets!
*
*/
//=============================================================================
var $gameNetwork = null;
var Nel_Online_Core_dataCreateGameObj = DataManager.createGameObjects;
DataManager.createGameObjects = function() {
Nel_Online_Core_dataCreateGameObj.call(this);
//Keep gameNetwork the same for New Game to keep login info
$gameNetwork = $gameNetwork || new Game_Network();
};
var Nel_MainCore_Online_PluginOpt = $plugins.filter(function(p)
{ return p.description.contains('<Online_Main_Core>');})[0].parameters;
function Game_Network() {
this.initialize.apply(this, arguments);
}
Game_Network.prototype.initialize = function() {
this._serverURL = String(Nel_MainCore_Online_PluginOpt['Server URL']);
this._firstHash = String(Nel_MainCore_Online_PluginOpt['First Hash']);
this._socket = {};
this._token =0;
};
Game_Network.prototype.decodedJWT = function(){
if ($gameNetwork._token===0) return false;
var b64 = $gameNetwork._token;
var body = b64.match(/[.](\S+)[.]/);
var buf = new Buffer(body[0], 'base64').toString("ascii");
var obj = JSON.parse(buf);
return obj;
};
Game_Network.prototype.connectSocketsAfterLogin = function(socket) {
//This runs right after logging in.
//Alias your own socket events
//(Similar to how you would add plugin commands)
};
Game_Network.prototype.connectSocket = function(socket_name, namespace) {
var url = this._serverURL;
this._socket[socket_name] = io.connect(url+namespace, {
query: 'token=' + $gameNetwork._token
});
var socket = this._socket[socket_name];
socket.on('connect', function () {
//Pass token on all POST/GET requests in the header
$.ajaxSetup({
headers: {
'x-access-token': $gameNetwork._token
}
});
console.log('Socket Authenticated');
});
socket.on('disconnect', function () {
console.log('Socket Disconnected');
});
};
================================================
FILE: game_resources/js/plugins/Online_Metrics.js
================================================
var Imported = Imported || {};
Imported.Online_Metrics = true;
var Nasty = Nasty || {};
(function () {
//=============================================================================
// Online Metrics
// Version: 1.0.1
//=============================================================================
//=============================================================================
/*:
* @plugindesc Very simple netwokred metrics for your game.
*<Online_Metrics>
*
* Requires Oniline Main Core and Server side setup to use.
* @author Nelderson
*
* @param Anonymous
* @desc If false requires users to be logged in with Login_Core
* @default true
*
*
* @help
* ============================================================================
* Introduction and Instructions
* ============================================================================
*
* Metrics allow you to store game data that you can use to project
* and show trends within your game.
*
* REQUIRES: Online_Main_Core
*
* There are two ways to send metrics to your database:
*
*
* 1. Plugin Command: SendMetrics <location>
*
* This plugin command will send the default metrics derfined under
* the default_metrics function in the plugin js file. Feel free to
* change the default values to match your game.
*
* <location> is the location where this is taking place for future reference.
*
* Ex. SendMetrics AfterBossBattle
*
* 2. Script Call: $gameSystem.sendMetrics(data);
*
* This script call passes a data object that is then uploaded to the database.
* The data object can hold any arbitrary data you want.
*
* Ex. $gameSystem.sendMetrics({
* goblin_kill_count = $gameVariables.value(35);
* save_count: $gameSystem._saveCount,
* escape_count: $gameSystem._escapeCount,
* battle_count: $gameSystem._battleCount,
* location: "AfterGoblinBattle"
* });
*
*/
//=============================================================================
var default_metrics =function() {
return{
save_count: $gameSystem._saveCount,
playtime: $gameSystem.playtime(),
battle_count: $gameSystem._battleCount,
win_count: $gameSystem._winCount,
escape_count: $gameSystem._escapeCount,
actors: $gameParty._actors,
gold: $gameParty._gold,
save_slot: DataManager.latestSavefileId()
};
};
Nasty.Parameters = $plugins.filter(function(p)
{ return p.description.contains('<Online_Metrics>');})[0].parameters;
var anonymousBool = Nasty.Parameters['Anonymous'];
var Online_Metrics_plugin_command = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
Online_Metrics_plugin_command.call(this,command, args);
if (command.toUpperCase() === 'SENDMETRICS') {
$gameSystem.sendMetricsFromPlugin(args[0]);
}
};
var Nel_Metrics_GS_init_Alias = Game_System.prototype.initialize;
Game_System.prototype.initialize = function(){
Nel_Metrics_GS_init_Alias.call(this);
this._metricsID = 'false';
};
Game_System.prototype.sendMetrics = function(data){
data.id = $gameSystem._metricsID;
$.post($gameNetwork._serverURL+'/metrics/datadump', data).done(function(data){
if (anonymousBool==='true'){
$gameSystem._metricsID = data;
}
});
};
Game_System.prototype.sendMetricsFromPlugin = function(data){
var metrics = default_metrics();
metrics.location = data;
metrics.id = $gameSystem._metricsID;
$.post($gameNetwork._serverURL+'/metrics/datadump', metrics).done(function(data){
if (anonymousBool==='true'){
$gameSystem._metricsID = data;
}
});
};
})();
================================================
FILE: game_resources/js/plugins/Online_Network_Players.js
================================================
var Imported = Imported || {};
Imported.Online_Network_Players = true;
(function () {
var Nasty = Nasty || {};
//=============================================================================
// Online Network Players
// Version: 1.0.10 - Fixed bug when in battle sprites clearing on map.
// Version: 1.0.9 - Added check to stop Game_Player refresh when null
// Version: 1.0.8 - Fixed bug for remove player when not on map
// Version: 1.0.7 - Fixed bug with NastyTextPop not being there
// Version: 1.0.6 - Added names above characters with Nasty_Text_Pop_Events.js
//=============================================================================
//=============================================================================
/*:
* @plugindesc Network Players for Neldersons Online Core
*<Online_Network_Players>
* @author Nelderson and Galv
*
* @param Net Player Map ID
* @desc Map ID for Net Player Spawn Event
* @default 1
*
* @param Net Player Event ID
* @desc Event ID for Net Player Spawn Event
* @default 1
*
* @param Show Username or Character Name
* @desc 0=Username, 1=Character Name
* @default 0
*
* @param Show Name Above Players Head
* @type boolean
* @on Yes
* @off No
* @desc Shows Username/Character name over Players Head
* @default true
*
* @param Player Text Options
* @desc This refers to the number in Nasty_Text_Pop_Events for text options
* @default 1
*
* @param Net Player Text Options
* @desc This refers to the number in Nasty_Text_Pop_Events for text options
* @default 1
*
* @help
* ============================================================================
* Introduction and Instructions
* ============================================================================
* This plugin allows you to see other players on the map.
* Add Nasty_Text_Pop_Events.js to see players names above their character
*
* Plugin Parameters:
*
* 1. Net Player Map ID
* -The Map ID the Netplayer Spawn event is located
*
* 2. Net Player Event ID
* -The Event ID the Netplayer Spawn event is located
*/
//=============================================================================
Nasty.Parameters = $plugins.filter(function(p)
{ return p.description.contains('<Online_Network_Players>');})[0].parameters;
var NetPlayerMap = Nasty.Parameters['Net Player Map ID'];
var NetPlayerEventID = Nasty.Parameters['Net Player Event ID'];
var NetPlayerNameType = Number(Nasty.Parameters['Show Username or Character Name']);
var showPlayersName = String(Nasty.Parameters['Show Name Above Players Head']);
var playerTextOptions = (Number(Nasty.Parameters['Player Text Options'])-1);
var netplayerTextOptions = (Number(Nasty.Parameters['Net Player Text Options'])-1);
var networkName = '';
var socket;
var networkPlayerid = 0;
var networkMapEvents = {};
var NetworkFlag = false;
var OnlineMV_NetPlayer_SocketConn_Alias = Game_Network.prototype.connectSocketsAfterLogin;
Game_Network.prototype.connectSocketsAfterLogin = function(){
OnlineMV_NetPlayer_SocketConn_Alias.call(this);
$gameNetwork.connectSocket('netplayers','/netplayers',false);
socket = $gameNetwork._socket.netplayers;
socket.on('MyID',function(data){
networkPlayerid = data.id; //Set Network ID
currentRoom = data.room;
NetworkFlag = true;
if (NetPlayerNameType===0){
networkName = data.name;
}
});
socket.on('NetworkPlayersXY', function(data){
if(!SceneManager._scene._spriteset || SceneManager._scene instanceof Scene_Battle) return;
var player = data.playerid;
var name = data.name;
var cx = data.x;
var cy = data.y;
var moveSpeed = data.moveSpeed;
var moveFrequenzy = data.moveFrequenzy;
var characterName = data.characterName;
var characterIndex = data.characterIndex;
//Make an event if net player isn't already there
if (networkMapEvents[player]===undefined){
var NetEvent = $gameMap.addNetworkPlayer(1, 1,name);
networkMapEvents[player] = NetEvent;
}
networkMapEvents[player].namepop = name;
networkMapEvents[player].textpop_flag = true;
// Update movement speed and frequenzy
networkMapEvents[player].setMoveSpeed(moveSpeed);
networkMapEvents[player].setMoveFrequency(moveFrequenzy);
//Continue on with updating xy position
var dir = data.direction;
networkMapEvents[player].moveStraight(dir);
//Sanity Check XY position
if (networkMapEvents[player].x!==data.x || networkMapEvents[player].y!==data.y){
networkMapEvents[player].setPosition(data.x, data.y);
}
//Set Player Sprite
networkMapEvents[player]._characterName = characterName;
networkMapEvents[player]._characterIndex = characterIndex;
});
socket.on('changeRoomVar', function(data){
currentRoom = data;
networkMapEvents = {};
});
socket.on('removePlayer', function(data){
if(!SceneManager._scene._spriteset || SceneManager._scene instanceof Scene_Battle) return;
var id = data.id;
//Just in case player hasn't moved and disconnects
if (!networkMapEvents[id]) return;
var player = networkMapEvents[id]._eventId;
var map = data.room;
$gameMap.clearNetworkPlayer(player);
delete networkMapEvents[id];
});
};
//================//
//Player Movement
//================//
Game_Player.prototype.moveByInput = function() {
if (!this.isMoving() && this.canMove()) {
var direction = this.getInputDirection();
if (direction > 0) {
$gameTemp.clearDestination();
} else if ($gameTemp.isDestinationValid()){
var x = $gameTemp.destinationX();
var y = $gameTemp.destinationY();
direction = this.findDirectionTo(x, y);
}
if (direction > 0) {
if (NetPlayerNameType===1) networkName=$gameParty.leader()._name;
//Send x,y info to server
this.executeMove(direction);
if (NetworkFlag){
socket.emit('DestinationXY', {
playerid: networkPlayerid,
direction: direction,
name: networkName,
x: this.x,
y: this.y,
moveSpeed: this.realMoveSpeed(),
moveFrequenzy: this.moveFrequency(),
characterName: this._characterName,
characterIndex: this._characterIndex
});
}
}
}
};
//=================================//
//Player Refresh for Text Over Self
//=================================//
var NetPlayer_GmePlayer_refresh_alias = Game_Player.prototype.refresh;
Game_Player.prototype.refresh = function() {
NetPlayer_GmePlayer_refresh_alias.call(this);
if(this.namepop===undefined) return;
if (showPlayersName==='false') return;
if (NetPlayerNameType===1) {
this.namepop = $gameParty.leader()._name;
}else{
this.namepop = networkName;
}
this.setTextOptions(playerTextOptions);
};
var NetPlayer_SceneBase_popScene = Scene_Base.prototype.popScene;
Scene_Base.prototype.popScene = function() {
NetPlayer_SceneBase_popScene.call(this);
if ($gamePlayer) $gamePlayer.refresh();
};
var NetPlayer_SceneBase_stop = Scene_Base.prototype.stop;
Scene_Base.prototype.stop = function() {
NetPlayer_SceneBase_stop.call(this);
if ($gamePlayer) $gamePlayer.refresh();
};
//==============================//
//Room Change When Changing Maps
//==============================//
var NetPlayer_SceneMap_Start_Alias = Scene_Map.prototype.start;
Scene_Map.prototype.start = function() {
NetPlayer_SceneMap_Start_Alias.call(this);
var mapId = $gameMap.mapId();
if (NetworkFlag){
//In case of menu or battle scene
if (currentRoom !== mapId.toString()){
socket.emit('changeRoom', mapId.toString());
}
}
};
var Online_NetPlayers_Map_CallMenu_Alias = Scene_Map.prototype.callMenu;
Scene_Map.prototype.callMenu = function() {
$gameMap.clearAllNetworkPlayerEvents();
networkMapEvents = {};
Online_NetPlayers_Map_CallMenu_Alias.call(this);
};
//========================//
//Net Player Event Creator
//========================//
DataManager.loadNetworkPlayerMapData = function() {
var mapId = NetPlayerMap;
var filename = 'Map%1.json'.format(mapId.padZero(3));
this.loadDataFile('$networkPlayerMap', filename);
};
DataManager.loadNetworkPlayerMapData();
Game_Map.prototype.addNetworkPlayer = function(x,y,playerid) {
var eId = this._events.length;
this._events[eId] = new Game_NetworkPlayer(this._mapId,eId,x,y, playerid);
SceneManager._scene._spriteset.createNetworkPlayer(eId);
return this._events[eId];
};
Game_Map.prototype.clearNetworkPlayer = function(eId) {
this._events[eId] = null;
SceneManager._scene._spriteset.clearNetworkPlayer(eId);
};
Game_Map.prototype.clearAllNetworkPlayerEvents = function() {
for (var i = 1; i < this._events.length; i++) {
if (!this._events[i]) continue;
if (this._events[i]._isNetworkPlayer){
this._events[i] = null;
}
SceneManager._scene._spriteset.clearAllNetworkPlayerEvents();
}
this.removeNullEvents();
};
Game_Map.prototype.removeNullEvents = function() {
for (var i = this._events.length - 1; i > 0; i--) {
if (this._events[i] === null) {
this._events.splice(i, 1);
} else {
break;
}
}
};
Spriteset_Map.prototype.createNetworkPlayer = function(id) {
var event = $gameMap._events[id];
var sId = this._characterSprites.length;
this._characterSprites[sId] = new Sprite_Character(event);
this._characterSprites[sId].update(); // To remove occsaional full-spriteset visible issue
this._tilemap.addChild(this._characterSprites[sId]);
};
Spriteset_Map.prototype.clearNetworkPlayer = function(eId) {
for (var i = 0; i < this._characterSprites.length; i++) {
var event = this._characterSprites[i]._character;
if (event._isNetworkPlayer && eId == event._eventId) {
this._tilemap.removeChild(this._characterSprites[i]);
}
}
};
Spriteset_Map.prototype.clearAllNetworkPlayerEvents = function() {
for (var i = 0; i < this._characterSprites.length; i++) {
var event = this._characterSprites[i]._character;
if (event._isNetworkPlayer) {
this._tilemap.removeChild(this._characterSprites[i]);
}
}
};
function Game_NetworkPlayer() {
this.initialize.apply(this, arguments);
}
Game_NetworkPlayer.prototype = Object.create(Game_Event.prototype);
Game_NetworkPlayer.prototype.constructor = Game_NetworkPlayer;
Game_NetworkPlayer.prototype.initialize = function(mapId,eventId,x,y, name) {
Game_Event.prototype.initialize.call(this,mapId,eventId);
this._isNetworkPlayer = true;
this.setPosition(x,y);
if (this.namepop===undefined){
console.log("You need Nasty_Text_Pop_Events for names to show!");
}else{
this.namepop = name;
this.setTextOptions(netplayerTextOptions);
}
};
Game_NetworkPlayer.prototype.event = function() {
return $networkPlayerMap.events[NetPlayerEventID];
};
})();
================================================
FILE: game_resources/sampleindex.html
================================================
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="viewport" content="user-scalable=no">
<link rel="icon" href="icon/icon.png" type="image/png">
<link rel="apple-touch-icon" href="icon/icon.png">
<link rel="stylesheet" type="text/css" href="fonts/gamefont.css">
<!-- Nel Add -->
<link rel="stylesheet" type="text/css" href="./css/bootstrap3.3.5.min.css" >
<link rel="stylesheet" type="text/css" href="./css/fontawesome4.7.0.min.css" >
<link rel="stylesheet" type="text/css" href="./css/MMO.css">
<!-- Nel Add -->
<title>Online_Core_Test</title>
</head>
<body style="background-color: black">
<!-- Nel Add -->
<script type="text/javascript" src="./js/libs/jquery-2.1.4.min.js"></script>
<script type="text/javascript" src="./js/libs/jquerymobile1.4.5.min.js"></script>
<link rel="stylesheet" type="text/css" href="./css/jquerymobile1.4.5.min.css">
<script type="text/javascript" src="./js/libs/crypto.sha1.js"></script>
<script type="text/javascript" src="./js/libs/socket.io-2.2.0.js"></script>
<!-- Nel Add -->
<script type="text/javascript" src="js/libs/pixi.js"></script>
<script type="text/javascript" src="js/libs/pixi-tilemap.js"></script>
<script type="text/javascript" src="js/libs/pixi-picture.js"></script>
<script type="text/javascript" src="js/libs/fpsmeter.js"></script>
<script type="text/javascript" src="js/libs/lz-string.js"></script>
<script type="text/javascript" src="js/rpg_core.js"></script>
<script type="text/javascript" src="js/rpg_managers.js"></script>
<script type="text/javascript" src="js/rpg_objects.js"></script>
<script type="text/javascript" src="js/rpg_scenes.js"></script>
<script type="text/javascript" src="js/rpg_sprites.js"></script>
<script type="text/javascript" src="js/rpg_windows.js"></script>
<script type="text/javascript" src="js/plugins.js"></script>
<script type="text/javascript" src="js/main.js"></script>
</body>
</html>
================================================
FILE: package.json
================================================
{
"name": "mvonline",
"version": "0.2.2",
"description": "Rpgmaker MV Online Server",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"engines": {
"node": "11.x"
},
"dependencies": {
"@sendgrid/mail": "^6.3.1",
"body-parser": "^1.18.3",
"connect-redis": "^3.4.0",
"express": "^4.16.4",
"jsonwebtoken": "^8.4.0",
"mailgun-js": "^0.22.0",
"mongoose": "^5.4.2",
"morgan": "^1.9.1",
"nodemailer": "^4.7.0",
"passport": "^0.4.0",
"passport-facebook": "^2.1.1",
"passport-google-oauth20": "^1.0.0",
"passport-local-mongoose": "^5.0.1",
"redis": "^2.8.0",
"sendgrid": "^5.2.3",
"socket.io": "2.2.0",
"socket.io-redis": "5.2.0",
"sticky-session": "1.1.2",
"swearjar": "^0.2.0",
"tracer": "^0.9.8"
},
"author": "Nelderson",
"license": "MIT"
}
================================================
FILE: server.js
================================================
//=============================================================================
// Nelderson's Online Core Server
// Version: 0.2.2 - Added abilty to limit users to one login.
// Version: 0.2.1
//=============================================================================
var express = require('express');
var app = express();
var server = require('http').createServer(app)
var io = require('socket.io')(server);
var sticky = require('sticky-session');
var config = require('./configurations/config');
var bodyParser = require('body-parser');
var logger = require('morgan'); //For development
var log = require('tracer').colorConsole(config.loggingConfig);
var loggedInUsers = {};
//Database Connction
require('./api_routes/loginDBConnection')();
var auth = require('./auth.js');
const redisAdapter = require('socket.io-redis');
io.adapter(redisAdapter(config.redisConnection));
app.use(logger('dev'));//For development
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: false}));
app.use(function(req,res,next){
res.setHeader('Access-Control-Allow-Origin', '*');
next();
});
if (!sticky.listen(server, config.port, {workers: process.env.MV_WORKER_COUNT || null})) {
// Master code
server.once('listening', function() {
log.info('Master Server started on port: '+ config.port);
});
}
else {
// Worker code
log.info('Worker is on bruh and running on port: '+ config.port);
//----------------------------------
// SET ROUTES FOR EXPRESS API HERE:
//----------------------------------
// No Authentication required:
app.use('/',require('./api_routes/login_routes'));
app.use('/metrics',require('./api_routes/metrics'));
// Authentication required:
app.use('/cloudsave',require('./api_routes/cloudsave.js'));
//Static Server - Used to serve static files (HTNL,PNG,etc.)
app.use('/static', express.static('public'));
//----------------------------------
// ADD SOCKET IO MODULES HERE:
//----------------------------------
// var exampleSocket = require('./socket_modules/exampleSocket');
var netplayers = require('./socket_modules/netplayer');
var chat = require('./socket_modules/chat');
var globalvar = require('./socket_modules/globalvar');
//Authorize socket connection with token from login
io.use(auth.authSocket)
//When first connected to Socket.io
io.on('connection', function(socket){
if(config.enforceOneUser){
var username = socket.user.name;
if (loggedInUsers[username]){
socket.to(loggedInUsers[username]).emit('firstShutDown',{});
socket.emit('secondShutDown',{});
io.of('/').connected[loggedInUsers[username]].disconnect(true);
socket.disconnect(true);
}
else {
loggedInUsers[username] = socket.id;
}
}
io.clients(function(error, clients){
if (error) throw error;
log.info("There are " + clients.length + " players connected");
});
socket.on('disconnect',function(data){
loggedInUsers[username] = null;
});
});
//----------------------------------
// BIND SOCKET IO MODULES HERE:
//----------------------------------
// exampleSocket(io);
netplayers(io);
chat(io);
globalvar(io);
} // <---Don't delete
================================================
FILE: socket_modules/chat.js
================================================
//Version: 0.1.2 - Added MyID call to pass client username
//Version: 0.1.1 - Cleanup of profanity filter.
var chatConfig = require('./../configurations/chat');
var config = require('./../configurations/config');
var log = require('tracer').colorConsole(config.loggingConfig);
var swearjar = require('swearjar');
var auth = require('../auth.js');
module.exports = function (sio) {
var io = sio.of('/chat');
io.use(auth.authSocket)
io.on('connection', function(socket) {
//Decoded Token
var token = socket.user;
var username = token.name;
socket.emit('MyID', {name: username});
socket.on('clientMessage',function(data) {
if (chatConfig.profanityFilter){
data.message = swearjar.censor(data.message);
}
io.emit('messageServer',data);
if (chatConfig.enableLogging){
log.info(username + ': ' + data.message);
}
});
});
};
================================================
FILE: socket_modules/exampleSocket.js
================================================
var config = require('./../configurations/config');
var log = require('tracer').colorConsole(config.loggingConfig);
module.exports = function (sio) {
//Set IO Roomspace
var io = sio.of('/example');
//Initialize socket
io.on('connection', function(socket){
socket.on('test',function(data){
log.info('test');
});
});
};
================================================
FILE: socket_modules/globalvar.js
================================================
var config = require('./../configurations/config');
var log = require('tracer').colorConsole(config.loggingConfig);
module.exports = function (sio) {
//Set IO Namespace
var io = sio.of('/globalvar');
//Initialize socket
io.on('connection', function(socket){
socket.on('switchDatatoServer',function(data){
socket.broadcast.emit('receivedSwitch', data);
});
socket.on('variableDatatoServer',function(data){
socket.broadcast.emit('receivedVariable', data);
});
});
};
================================================
FILE: socket_modules/netplayer.js
================================================
// Version: 0.1.0 - Cleanup of initial Version
var auth = require('../auth.js');
module.exports = function (sio) {
var io = sio.of('/netplayers');
io.use(auth.authSocket)
io.on('connection', function(socket){
var token = socket.user
var username = token.name;
var id = socket.id;
var currentRoom = '0'; //Room names are based off Map ID
socket.emit('MyID', {id: id, room: currentRoom, name: username});
//Gather XY Position and broadcast to all other players
socket.on('DestinationXY', function(data){
socket.broadcast.to(currentRoom).emit('NetworkPlayersXY', data);
});
socket.on('changeRoom', function(data){
socket.broadcast.to(currentRoom).emit('removePlayer',{id: id, room: currentRoom});
socket.leave(currentRoom);
currentRoom = data;
socket.join(data);
socket.emit('changeRoomVar', data);
});
socket.on('disconnect', function(socket){
io.in(currentRoom).emit('removePlayer',{id: id, room: currentRoom});
});
});
};
gitextract_htn83e9x/
├── .gitignore
├── CHANGELOG.md
├── LICENSE
├── Procfile
├── README.md
├── READMEs/
│ ├── Chat.md
│ ├── CloudSave.md
│ ├── Cors.md
│ ├── GlobalVariables.md
│ ├── Metrics.md
│ └── NetPlayers.md
├── api_routes/
│ ├── LoginSchema/
│ │ └── Account.js
│ ├── cloudsave.js
│ ├── cors.js
│ ├── example.js
│ ├── loginDBConnection.js
│ ├── login_routes.js
│ └── metrics.js
├── app.json
├── auth.js
├── configurations/
│ ├── chat.js
│ ├── config.js
│ └── cors.js
├── game_resources/
│ ├── css/
│ │ └── MMO.css
│ ├── js/
│ │ ├── libs/
│ │ │ ├── crypto.sha1.js
│ │ │ └── socket.io-2.2.0.js
│ │ └── plugins/
│ │ ├── Nasty_Text_Pop_Events.js
│ │ ├── Online_Chat.js
│ │ ├── Online_CloudSave.js
│ │ ├── Online_GlobalVars.js
│ │ ├── Online_Login_Core.js
│ │ ├── Online_Main_Core.js
│ │ ├── Online_Metrics.js
│ │ └── Online_Network_Players.js
│ └── sampleindex.html
├── package.json
├── server.js
└── socket_modules/
├── chat.js
├── exampleSocket.js
├── globalvar.js
└── netplayer.js
SYMBOL INDEX (110 symbols across 5 files)
FILE: game_resources/js/libs/socket.io-2.2.0.js
function e (line 6) | function e(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,lo...
function r (line 6) | function r(t,e){"object"===("undefined"==typeof t?"undefined":o(t))&&(e=...
function r (line 6) | function r(t,e){var n=t;e=e||"undefined"!=typeof location&&location,null...
function o (line 6) | function o(){return!("undefined"==typeof window||!window.process||"rende...
function i (line 6) | function i(t){var n=this.useColors;if(t[0]=(n?"%c":"")+this.namespace+(n...
function s (line 6) | function s(){return"object"==typeof console&&console.log&&Function.proto...
function a (line 6) | function a(t){try{null==t?e.storage.removeItem("debug"):e.storage.debug=...
function c (line 6) | function c(){var t;try{t=e.storage.debug}catch(n){}return!t&&"undefined"...
function p (line 6) | function p(){try{return window.localStorage}catch(t){}}
function n (line 6) | function n(){throw new Error("setTimeout has not been defined")}
function r (line 6) | function r(){throw new Error("clearTimeout has not been defined")}
function o (line 6) | function o(t){if(u===setTimeout)return setTimeout(t,0);if((u===n||!u)&&s...
function i (line 6) | function i(t){if(h===clearTimeout)return clearTimeout(t);if((h===r||!h)&...
function s (line 6) | function s(){y&&l&&(y=!1,l.length?d=l.concat(d):m=-1,d.length&&a())}
function a (line 6) | function a(){if(!y){var t=o(s);y=!0;for(var e=d.length;e;){for(l=d,d=[];...
function c (line 6) | function c(t,e){this.fun=t,this.array=e}
function p (line 6) | function p(){}
function r (line 6) | function r(t){var n,r=0;for(n in t)r=(r<<5)-r+t.charCodeAt(n),r|=0;retur...
function o (line 6) | function o(t){function n(){if(n.enabled){var t=n,r=+new Date,i=r-(o||r);...
function i (line 6) | function i(){var t=e.instances.indexOf(this);return t!==-1&&(e.instances...
function s (line 6) | function s(t){e.save(t),e.names=[],e.skips=[];var n,r=("string"==typeof ...
function a (line 6) | function a(){e.enable("")}
function c (line 6) | function c(t){if("*"===t[t.length-1])return!0;var n,r;for(n=0,r=e.skips....
function p (line 6) | function p(t){return t instanceof Error?t.stack||t.message:t}
function n (line 6) | function n(t){if(t=String(t),!(t.length>100)){var e=/^((?:\d+)?\.?\d+) *...
function r (line 6) | function r(t){return t>=p?Math.round(t/p)+"d":t>=c?Math.round(t/c)+"h":t...
function o (line 6) | function o(t){return i(t,p,"day")||i(t,c,"hour")||i(t,a,"minute")||i(t,s...
function i (line 6) | function i(t,e,n){if(!(t<e))return t<1.5*e?Math.floor(t/e)+" "+n:Math.ce...
function r (line 6) | function r(){}
function o (line 6) | function o(t){var n=""+t.type;if(e.BINARY_EVENT!==t.type&&e.BINARY_ACK!=...
function i (line 6) | function i(t){try{return JSON.stringify(t)}catch(e){return!1}}
function s (line 6) | function s(t,e){function n(t){var n=d.deconstructPacket(t),r=o(n.packet)...
function a (line 6) | function a(){this.reconstructor=null}
function c (line 6) | function c(t){var n=0,r={type:Number(t.charAt(0))};if(null==e.types[r.ty...
function p (line 6) | function p(t){try{return JSON.parse(t)}catch(e){return!1}}
function u (line 6) | function u(t){this.reconPack=t,this.buffers=[]}
function h (line 6) | function h(t){return{type:e.ERROR,data:"parser error: "+t}}
function r (line 6) | function r(t){if(t)return o(t)}
function o (line 6) | function o(t){for(var e in r.prototype)t[e]=r.prototype[e];return t}
function n (line 6) | function n(){this.off(t,n),e.apply(this,arguments)}
function r (line 6) | function r(t,e){if(!t)return t;if(s(t)){var n={_placeholder:!0,num:e.len...
function o (line 6) | function o(t,e){if(!t)return t;if(t&&t._placeholder)return e[t.num];if(i...
function n (line 6) | function n(t,a,u){if(!t)return t;if(c&&t instanceof Blob||p&&t instanceo...
function n (line 6) | function n(t){return r&&Buffer.isBuffer(t)||o&&(t instanceof ArrayBuffer...
function r (line 6) | function r(t,e){if(!(this instanceof r))return new r(t,e);t&&"object"===...
function n (line 6) | function n(){~f(o.connecting,r)||o.connecting.push(r)}
function r (line 6) | function r(t,e){return this instanceof r?(e=e||{},t&&"object"==typeof t&...
function o (line 6) | function o(t){var e={};for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);r...
function e (line 6) | function e(){if(f.onlyBinaryUpgrades){var e=!this.supportsBinary&&f.tran...
function n (line 6) | function n(){h||(h=!0,p(),u.close(),u=null)}
function o (line 6) | function o(e){var r=new Error("probe error: "+e);r.transport=u.name,n(),...
function i (line 6) | function i(){o("transport closed")}
function s (line 6) | function s(){o("socket closed")}
function c (line 6) | function c(t){u&&t.name!==u.name&&(a('"%s" works - aborting "%s"',t.name...
function p (line 6) | function p(){u.removeListener("open",e),u.removeListener("error",o),u.re...
function t (line 6) | function t(){r.onClose("forced close"),a("socket closing - telling trans...
function e (line 6) | function e(){r.removeListener("upgrade",e),r.removeListener("upgradeErro...
function n (line 6) | function n(){r.once("upgrade",e),r.once("upgradeError",e)}
function r (line 6) | function r(t){var e,n=!1,r=!1,a=!1!==t.jsonp;
function r (line 7) | function r(){}
function o (line 7) | function o(t){if(c.call(this,t),this.requestTimeout=t.requestTimeout,thi...
function i (line 7) | function i(t){this.method=t.method||"GET",this.uri=t.uri,this.xd=!!t.xd,...
function s (line 7) | function s(){for(var t in i.requests)i.requests.hasOwnProperty(t)&&i.req...
function r (line 7) | function r(t){var e=t&&t.forceBase64;u&&!e||(this.supportsBinary=!1),o.c...
function e (line 7) | function e(){p("paused"),n.readyState="paused",t()}
function t (line 7) | function t(){p("writing close packet"),e.write([{type:"close"}])}
function r (line 7) | function r(t){this.path=t.path,this.hostname=t.hostname,this.port=t.port...
function r (line 7) | function r(t,n){var r="b"+e.packets[t.type]+t.data.data;return n(r)}
function o (line 7) | function o(t,n,r){if(!n)return e.encodeBase64Packet(t,r);var o=t.data,i=...
function i (line 7) | function i(t,n,r){if(!n)return e.encodeBase64Packet(t,r);var o=new FileR...
function s (line 7) | function s(t,n,r){if(!n)return e.encodeBase64Packet(t,r);if(g)return i(t...
function a (line 7) | function a(t){try{t=d.decode(t,{strict:!1})}catch(e){return!1}return t}
function c (line 7) | function c(t,e,n){for(var r=new Array(t.length),o=l(t.length,n),i=functi...
function o (line 7) | function o(t){return t.length+":"+t}
function i (line 7) | function i(t,r){e.encodePacket(t,!!s&&n,!1,function(t){r(null,o(t))})}
function r (line 7) | function r(t,n){e.encodePacket(t,!0,!0,function(t){return n(null,t)})}
function r (line 7) | function r(t,n){e.encodePacket(t,!0,!0,function(t){var e=new Uint8Array(...
function r (line 7) | function r(t){if(!t||"object"!=typeof t)return!1;if(o(t)){for(var e=0,n=...
function n (line 7) | function n(t,e,n){function o(t,r){if(o.count<=0)throw new Error("after c...
function r (line 7) | function r(){}
function n (line 7) | function n(t){for(var e,n,r=[],o=0,i=t.length;o<i;)e=t.charCodeAt(o++),e...
function r (line 7) | function r(t){for(var e,n=t.length,r=-1,o="";++r<n;)e=t[r],e>65535&&(e-=...
function o (line 7) | function o(t,e){if(t>=55296&&t<=57343){if(e)throw Error("Lone surrogate ...
function i (line 7) | function i(t,e){return d(t>>e&63|128)}
function s (line 7) | function s(t,e){if(0==(4294967168&t))return d(t);var n="";return 0==(429...
function a (line 7) | function a(t,e){e=e||{};for(var r,o=!1!==e.strict,i=n(t),a=i.length,c=-1...
function c (line 7) | function c(){if(l>=f)throw Error("Invalid byte index");var t=255&h[l];if...
function p (line 7) | function p(t){var e,n,r,i,s;if(l>f)throw Error("Invalid byte index");if(...
function u (line 7) | function u(t,e){e=e||{};var o=!1!==e.strict;h=n(t),f=h.length,l=0;for(va...
function n (line 8) | function n(t){return t.map(function(t){if(t.buffer instanceof ArrayBuffe...
function r (line 8) | function r(t,e){e=e||{};var r=new i;return n(t).forEach(function(t){r.ap...
function o (line 8) | function o(t,e){return new Blob(n(t),e||{})}
function n (line 8) | function n(t){var e="";do e=s[t%a]+e,t=Math.floor(t/a);while(t>0);return e}
function r (line 8) | function r(t){var e=0;for(u=0;u<t.length;u++)e=e*a+c[t.charAt(u)];return e}
function o (line 8) | function o(){var t=n(+new Date);return t!==i?(p=0,i=t):t+"."+n(p++)}
function r (line 8) | function r(){}
function o (line 8) | function o(){return"undefined"!=typeof self?self:"undefined"!=typeof win...
function i (line 8) | function i(t){if(s.call(this,t),this.query=this.query||{},!c){var e=o();...
function n (line 8) | function n(){r(),e()}
function r (line 8) | function r(){if(o.iframe)try{o.form.removeChild(o.iframe)}catch(t){o.onE...
function r (line 8) | function r(t){var e=t&&t.forceBase64;e&&(this.supportsBinary=!1),this.pe...
function e (line 8) | function e(){n.emit("flush"),setTimeout(function(){n.writable=!0,n.emit(...
function r (line 8) | function r(t,e,n){this.io=t,this.nsp=e,this.json=this,this.ids=0,this.ac...
function n (line 8) | function n(t,e){var n=[];e=e||0;for(var r=e||0;r<t.length;r++)n[r-e]=t[r...
function n (line 8) | function n(t,e,n){return t.on(e,n),{destroy:function(){t.removeListener(...
function n (line 8) | function n(t){t=t||{},this.ms=t.min||100,this.max=t.max||1e4,this.factor...
FILE: game_resources/js/plugins/Nasty_Text_Pop_Events.js
function Window_CharacterPop (line 714) | function Window_CharacterPop() {
FILE: game_resources/js/plugins/Online_Login_Core.js
function MMO_Scene_Title (line 76) | function MMO_Scene_Title() {
FILE: game_resources/js/plugins/Online_Main_Core.js
function Game_Network (line 43) | function Game_Network() {
FILE: game_resources/js/plugins/Online_Network_Players.js
function Game_NetworkPlayer (line 304) | function Game_NetworkPlayer() {
Condensed preview — 41 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (201K chars).
[
{
"path": ".gitignore",
"chars": 811,
"preview": "#MacOSX Stuffs\n.DS_Store\n.DS_Store?\n\n#public folder\npublic\n\n#Configuration Folder\nserver/configurations/config.js\n\n# Log"
},
{
"path": "CHANGELOG.md",
"chars": 1006,
"preview": "# MV Online Version 0.2.0 Release Notes:\n\n## Summary\nThere are 2 main points that are different from 0.1.0\n\n- package.js"
},
{
"path": "LICENSE",
"chars": 1085,
"preview": "MIT License\n\nCopyright (c) 2017 Matthew Cipriano (Nelderson)\n\nPermission is hereby granted, free of charge, to any perso"
},
{
"path": "Procfile",
"chars": 19,
"preview": "web: node server.js"
},
{
"path": "README.md",
"chars": 2596,
"preview": "MV Online Core Documentation\n==========================\n\nRequirements\n-------------\nNode.js and RPGMaker MV\n\nInstallatio"
},
{
"path": "READMEs/Chat.md",
"chars": 533,
"preview": "MV Online Chat Documentation\n==========================\n\nIntroduction\n-------------\n\nThe Online Chat Socket Module allow"
},
{
"path": "READMEs/CloudSave.md",
"chars": 361,
"preview": "MV Cloud Save Documentation\n==========================\n\nIntroduction\n-------------\n\n`Cloud Save` allows you to store gam"
},
{
"path": "READMEs/Cors.md",
"chars": 359,
"preview": "MV Cors Documentation\n==========================\n\nIntroduction\n-------------\n\n`api_routes/Cors.js` allows you to your se"
},
{
"path": "READMEs/GlobalVariables.md",
"chars": 561,
"preview": "MV Online Global Variables Documentation\n==========================\n\nIntroduction\n-------------\n\nThe Online Global Varia"
},
{
"path": "READMEs/Metrics.md",
"chars": 546,
"preview": "MV Online Metrics Documentation\n==========================\n\nIntroduction\n-------------\n\n`Metrics` allows you to store ga"
},
{
"path": "READMEs/NetPlayers.md",
"chars": 522,
"preview": "MV Net Players Documentation\n==========================\n\nIntroduction\n-------------\n\nThe Online Net Players Socket Modul"
},
{
"path": "api_routes/LoginSchema/Account.js",
"chars": 1221,
"preview": "//Version 0.1.0 - Added fields for password reset logic\n\nvar mongoose = require('mongoose');\nvar Schema = mongoose.Schem"
},
{
"path": "api_routes/cloudsave.js",
"chars": 1789,
"preview": "var mongoose = require(\"mongoose\");\nvar express = require('express');\nvar authAPI = require('../auth.js').authAPI;\nvar r"
},
{
"path": "api_routes/cors.js",
"chars": 915,
"preview": "//----------------------------------\n// Require file & Router :\n//----------------------------------\nvar config = requir"
},
{
"path": "api_routes/example.js",
"chars": 309,
"preview": "var express = require('express');\nvar authAPI = require('../auth.js').authAPI;\nvar router = express.Router();\n\n\n//Need t"
},
{
"path": "api_routes/loginDBConnection.js",
"chars": 386,
"preview": "module.exports = function(){\n var config = require('../configurations/config');\n var mongoose = require('mongoose');\n "
},
{
"path": "api_routes/login_routes.js",
"chars": 8922,
"preview": "var crypto = require('crypto');\nvar express = require('express');\nvar config = require('../configurations/config');\nvar "
},
{
"path": "api_routes/metrics.js",
"chars": 2462,
"preview": "var mongoose = require('mongoose');\nvar Schema = mongoose.Schema;\nvar express = require('express');\nvar authAPI = requir"
},
{
"path": "app.json",
"chars": 1753,
"preview": "{\n \"name\": \"MV Online\",\n \"description\": \"MV Online system created by Nelderson\",\n \"repository\": \"https://github.com/N"
},
{
"path": "auth.js",
"chars": 1360,
"preview": "var jwt = require('jsonwebtoken');\nvar config = require('./configurations/config');\n\n var authAPI = function(req, res, n"
},
{
"path": "configurations/chat.js",
"chars": 234,
"preview": "var Config = module.exports = {\n\t//---------------------\n\t//Main Configurations\n\t//---------------------\n\tenableLogging:"
},
{
"path": "configurations/config.js",
"chars": 1749,
"preview": "var Config = module.exports = {\n //---------------------\n //Main Configurations\n //---------------------\n port: pro"
},
{
"path": "configurations/cors.js",
"chars": 311,
"preview": "var Config = module.exports = {\n //---------------------\n //Cors Configurations\n //---------------------\n\n MyCorsHos"
},
{
"path": "game_resources/css/MMO.css",
"chars": 586,
"preview": "/*\n* @Author: Vinxce\n* @Date: 2015-10-27 10:55:44\n* @Last Modified by: Vinxce\n* @Last Modified time: 2015-10-27 21:3"
},
{
"path": "game_resources/js/libs/crypto.sha1.js",
"chars": 4293,
"preview": "/*\nCryptoJS v3.1.2\ncode.google.com/p/crypto-js\n(c) 2009-2013 by Jeff Mott. All rights reserved.\ncode.google.com/p/crypto"
},
{
"path": "game_resources/js/libs/socket.io-2.2.0.js",
"chars": 62421,
"preview": "/*!\n * Socket.IO v2.2.0\n * (c) 2014-2018 Guillermo Rauch\n * Released under the MIT License.\n */\n!function(t,e){\"object\"="
},
{
"path": "game_resources/js/plugins/Nasty_Text_Pop_Events.js",
"chars": 26739,
"preview": "//=============================================================================\n// Nasty Text Pop Over Event\n// Version:"
},
{
"path": "game_resources/js/plugins/Online_Chat.js",
"chars": 14213,
"preview": "var Imported = Imported || {};\nImported.Online_Chat = true;\n\n(function () {\nvar Nasty = Nasty || {};\n//================="
},
{
"path": "game_resources/js/plugins/Online_CloudSave.js",
"chars": 1807,
"preview": "/*\nOnline Cloud Save v.0.1.1\n\nTake data from one source and be able to load it on other devices\n\nSign in > Check the Dat"
},
{
"path": "game_resources/js/plugins/Online_GlobalVars.js",
"chars": 3932,
"preview": "//=============================================================================\n// Online Global Variables and Switches\n"
},
{
"path": "game_resources/js/plugins/Online_Login_Core.js",
"chars": 21158,
"preview": "var Imported = Imported || {};\nImported.Online_Login_Core = true;\n\n(function () {\n\tvar Nasty = Nasty || {};\n//=========="
},
{
"path": "game_resources/js/plugins/Online_Main_Core.js",
"chars": 2849,
"preview": "var Imported = Imported || {};\nImported.Online_Main_Core = true;\n//====================================================="
},
{
"path": "game_resources/js/plugins/Online_Metrics.js",
"chars": 3646,
"preview": "var Imported = Imported || {};\nImported.Online_Metrics = true;\nvar Nasty = Nasty || {};\n\n(function () {\n//=============="
},
{
"path": "game_resources/js/plugins/Online_Network_Players.js",
"chars": 10656,
"preview": "var Imported = Imported || {};\nImported.Online_Network_Players = true;\n\n(function () {\nvar Nasty = Nasty || {};\n//======"
},
{
"path": "game_resources/sampleindex.html",
"chars": 2315,
"preview": "<!DOCTYPE html>\n<html>\n <head>\n <meta charset=\"UTF-8\">\n <meta name=\"apple-mobile-web-app-capable\" conte"
},
{
"path": "package.json",
"chars": 889,
"preview": "{\n \"name\": \"mvonline\",\n \"version\": \"0.2.2\",\n \"description\": \"Rpgmaker MV Online Server\",\n \"main\": \"server.js\",\n \"sc"
},
{
"path": "server.js",
"chars": 3243,
"preview": "//=============================================================================\n// Nelderson's Online Core Server\n// Ver"
},
{
"path": "socket_modules/chat.js",
"chars": 865,
"preview": "//Version: 0.1.2 - Added MyID call to pass client username\n//Version: 0.1.1 - Cleanup of profanity filter.\n\nvar chatConf"
},
{
"path": "socket_modules/exampleSocket.js",
"chars": 343,
"preview": "var config = require('./../configurations/config');\nvar log = require('tracer').colorConsole(config.loggingConfig);\n\nmod"
},
{
"path": "socket_modules/globalvar.js",
"chars": 508,
"preview": "var config = require('./../configurations/config');\nvar log = require('tracer').colorConsole(config.loggingConfig);\n\nmod"
},
{
"path": "socket_modules/netplayer.js",
"chars": 1029,
"preview": "// Version: 0.1.0 - Cleanup of initial Version\nvar auth = require('../auth.js');\n\nmodule.exports = function (sio) {\n\n v"
}
]
About this extraction
This page contains the full source code of the Nelderson/MV_Online GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 41 files (186.8 KB), approximately 51.8k tokens, and a symbol index with 110 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.