Commit 1505e18f authored by nanahira's avatar nanahira

Merge branch 'master' into tcg_random

parents 2d0d4acb 71eb7a7c
......@@ -23,7 +23,8 @@ ygopro-2pick
/node_modules
/ssl
/ygosrv233
/dash.json
/challonge
/logs
test*
*.heapsnapshot
......
......@@ -128,7 +128,8 @@
"post_score_midduel": true,
"cache_ttl": 60000,
"api_key": "11",
"tournament_id": "22"
"tournament_id": "22",
"use_custom_module": false
},
"deck_log": {
"enabled": false,
......
......@@ -140,7 +140,8 @@
"post_score_midduel": true,
"cache_ttl": 60000,
"api_key": "123",
"tournament_id": "456"
"tournament_id": "456",
"use_custom_module": false
},
"deck_log": {
"enabled": false,
......@@ -174,7 +175,6 @@
"show_ip": false,
"show_info": true,
"log_save_path": "./config/",
"password": "123456",
"port": 7933
},
"side_restrict": {
......@@ -190,7 +190,6 @@
"pre_util": {
"enabled": false,
"port": 7944,
"password": "123456",
"git_html_path": "../mercury233.github.io/",
"html_path": "../mercury233.github.io/ygosrv233/",
"html_filename": "pre.html",
......@@ -269,7 +268,6 @@
"update_util": {
"enabled": false,
"port": 7955,
"password": "123456",
"git_html_path": "../ygo233-web/",
"html_path": "../ygo233-web/",
"cdb_path": "./ygopro/cards.cdb",
......@@ -295,7 +293,6 @@
},
"http": {
"port": 7922,
"password": "123456",
"websocket_roomlist": false,
"public_roomlist": false,
"show_ip": false,
......
......@@ -65,5 +65,50 @@
"1": []
},
"players": {}
},
"users": {
"file": "./config/admin_user.json",
"permission_examples": {
"sudo": {
"get_rooms": true,
"duel_log": true,
"download_replay": true,
"clear_duel_log": true,
"deck_dashboard_read": true,
"deck_dashboard_write": true,
"shout": true,
"stop": true,
"change_settings": true,
"ban_user": true,
"kick_user": true,
"start_death": true,
"pre_dashboard": true,
"update_dashboard": true,
"vip": true
},
"judge": {
"get_rooms": true,
"duel_log": true,
"download_replay": true,
"deck_dashboard_read": true,
"deck_dashboard_write": true,
"shout": true,
"kick_user": true,
"start_death": true
},
"streamer": {
"get_rooms": true,
"duel_log": true,
"download_replay": true,
"deck_dashboard_read": true
}
},
"users": {
"root": {
"password": "123456",
"enabled": false,
"permissions": "sudo"
}
}
}
}
\ No newline at end of file
}
###
Main script of new dashboard account system.
The account list file is stored at `./config/admin_user.json`. The users are stored at `users`.
The key is the username. The `permissions` field could be a string, using a permission set from the example, or an object, to define a specific set of permissions.
eg. An account for a judge could be as follows, to use the default permission of judges,
"username": {
"password": "123456",
"enabled": true,
"permissions": "judge"
},
or as follows, to use a specific set of permissions.
"username": {
"password": "123456",
"enabled": true,
"permissions": {
"get_rooms": true,
"duel_log": true,
"download_replay": true,
"deck_dashboard_read": true,
"deck_dashboard_write": true,
"shout": true,
"kick_user": true,
"start_death": true
}
},
###
fs = require 'fs'
loadJSON = require('load-json-file').sync
moment = require 'moment'
moment.locale('zh-cn', {
relativeTime: {
future: '%s内',
past: '%s前',
s: '%d秒',
m: '1分钟',
mm: '%d分钟',
h: '1小时',
hh: '%d小时',
d: '1天',
dd: '%d天',
M: '1个月',
MM: '%d个月',
y: '1年',
yy: '%d年'
}
})
if not fs.existsSync('./logs')
fs.mkdirSync('./logs')
add_log = (message) ->
mt = moment()
text = mt.format('YYYY-MM-DD HH:mm:ss') + " --> " + message + "\n"
console.log(text)
res = false
try
fs.appendFileSync("./logs/"+mt.format('YYYY-MM-DD')+".log", text)
res = true
catch
res = false
return
default_data = loadJSON('./data/default_data.json')
setting_save = (settings) ->
fs.writeFileSync(settings.file, JSON.stringify(settings, null, 2))
return
default_data = loadJSON('./data/default_data.json')
try
users = loadJSON('./config/admin_user.json')
catch
users = default_data.users
setting_save(users)
save = () ->
setting_save(users)
return
reload = () ->
user_backup = users
try
users = loadJSON('./config/admin_user.json')
catch
users = user_backup
add_log("Invalid user data JSON")
return
check_permission = (user, permission_required) ->
_permission = user.permissions
permission = _permission
if typeof(permission) != 'object'
permission = users.permission_examples[_permission]
if !permission
add_log("Permision not set:"+_permission)
return false
return permission[permission_required]
@auth = (name, pass, permission_required, action = 'unknown') ->
reload()
user = users.users[name]
if !user
add_log("Unknown user login. User: "+ name+", Permission needed: "+ permission_required+", Action: " +action)
return false
if user.password != pass
add_log("Unauthorized user login. User: "+ name+", Permission needed: "+ permission_required+", Action: " +action)
return false
if !user.enabled
add_log("Disabled user login. User: "+ name+", Permission needed: "+ permission_required+", Action: " +action)
return false
if !check_permission(user, permission_required)
add_log("Permission denied. User: "+ name+", Permission needed: "+ permission_required+", Action: " +action)
return false
add_log("Operation success. User: "+ name+", Permission needed: "+ permission_required+", Action: " +action)
return true
@add_user = (name, pass, enabled, permissions) ->
reload()
if users.users[name]
return false
users.users[name] = {
"password": pass,
"enabled": enabled,
"permissions": permissions
}
save()
return true
@delete_user = (name) ->
reload()
if !users.users[name]
return false
delete users.users[name]
save()
return true
@update_user = (name, key, value) ->
reload()
if !users.users[name]
return false
users.users[name][key] = value
save()
return true
// Generated by CoffeeScript 1.12.7
/*
Main script of new dashboard account system.
The account list file is stored at `./config/admin_user.json`. The users are stored at `users`.
The key is the username. The `permissions` field could be a string, using a permission set from the example, or an object, to define a specific set of permissions.
eg. An account for a judge could be as follows, to use the default permission of judges,
"username": {
"password": "123456",
"enabled": true,
"permissions": "judge"
},
or as follows, to use a specific set of permissions.
"username": {
"password": "123456",
"enabled": true,
"permissions": {
"get_rooms": true,
"duel_log": true,
"download_replay": true,
"deck_dashboard_read": true,
"deck_dashboard_write": true,
"shout": true,
"kick_user": true,
"start_death": true
}
},
*/
(function() {
var add_log, check_permission, default_data, fs, loadJSON, moment, reload, save, setting_save, users;
fs = require('fs');
loadJSON = require('load-json-file').sync;
moment = require('moment');
moment.locale('zh-cn', {
relativeTime: {
future: '%s内',
past: '%s前',
s: '%d秒',
m: '1分钟',
mm: '%d分钟',
h: '1小时',
hh: '%d小时',
d: '1天',
dd: '%d天',
M: '1个月',
MM: '%d个月',
y: '1年',
yy: '%d年'
}
});
if (!fs.existsSync('./logs')) {
fs.mkdirSync('./logs');
}
add_log = function(message) {
var mt, res, text;
mt = moment();
text = mt.format('YYYY-MM-DD HH:mm:ss') + " --> " + message + "\n";
console.log(text);
res = false;
try {
fs.appendFileSync("./logs/" + mt.format('YYYY-MM-DD') + ".log", text);
res = true;
} catch (error) {
res = false;
}
};
default_data = loadJSON('./data/default_data.json');
setting_save = function(settings) {
fs.writeFileSync(settings.file, JSON.stringify(settings, null, 2));
};
default_data = loadJSON('./data/default_data.json');
try {
users = loadJSON('./config/admin_user.json');
} catch (error) {
users = default_data.users;
setting_save(users);
}
save = function() {
setting_save(users);
};
reload = function() {
var user_backup;
user_backup = users;
try {
users = loadJSON('./config/admin_user.json');
} catch (error) {
users = user_backup;
add_log("Invalid user data JSON");
}
};
check_permission = function(user, permission_required) {
var _permission, permission;
_permission = user.permissions;
permission = _permission;
if (typeof permission !== 'object') {
permission = users.permission_examples[_permission];
}
if (!permission) {
add_log("Permision not set:" + _permission);
return false;
}
return permission[permission_required];
};
this.auth = function(name, pass, permission_required, action) {
var user;
if (action == null) {
action = 'unknown';
}
reload();
user = users.users[name];
if (!user) {
add_log("Unknown user login. User: " + name + ", Permission needed: " + permission_required + ", Action: " + action);
return false;
}
if (user.password !== pass) {
add_log("Unauthorized user login. User: " + name + ", Permission needed: " + permission_required + ", Action: " + action);
return false;
}
if (!user.enabled) {
add_log("Disabled user login. User: " + name + ", Permission needed: " + permission_required + ", Action: " + action);
return false;
}
if (!check_permission(user, permission_required)) {
add_log("Permission denied. User: " + name + ", Permission needed: " + permission_required + ", Action: " + action);
return false;
}
add_log("Operation success. User: " + name + ", Permission needed: " + permission_required + ", Action: " + action);
return true;
};
this.add_user = function(name, pass, enabled, permissions) {
reload();
if (users.users[name]) {
return false;
}
users.users[name] = {
"password": pass,
"enabled": enabled,
"permissions": permissions
};
save();
return true;
};
this.delete_user = function(name) {
reload();
if (!users.users[name]) {
return false;
}
delete users.users[name];
save();
return true;
};
this.update_user = function(name, key, value) {
reload();
if (!users.users[name]) {
return false;
}
users.users[name][key] = value;
save();
return true;
};
}).call(this);
/*
ygopro-generate-result.js
ygopro tournament result generator
Author: Yuzurisa
License: MIT
Will generate the tournament result in a specific format.
*/
var output_path = "./config"
if (process.argv[2])
output_path = process.argv[2];
const loadJSON = require('load-json-file').sync;
const fs = require('fs');
const settings = loadJSON('./config/config.json');
const challonge_config = settings.modules.challonge;
if (challonge_config.enabled) {
challonge = require('challonge').createClient({
apiKey: challonge_config.api_key
});
} else {
console.error("Challonge is not enabled.");
return 1;
}
var name_list = {};
var results = {};
console.log("Requesting player datas from Challonge.");
challonge.participants.index({
id: challonge_config.tournament_id,
callback: (error, data) => {
if (error || !data) {
console.error(error);
return;
}
for (var k in data) {
const player = data[k];
if (!player || !player.participant) {
continue;
}
const player_info = player.participant;
const name = player_info.name;
const id = player_info.id;
name_list[id] = name;
}
console.log("Requesting match datas from Challonge.");
//for (var i = 1; i <=)
challonge.matches.index({
id: challonge_config.tournament_id,
callback: (error, data) => {
if (error || !data) {
console.error(error);
return;
}
for (var k in data) {
const match = data[k];
if (!match || !match.match) {
continue;
}
const match_info = match.match;
if (match_info.state != "complete") {
continue;
}
const sign = match_info.identifier;
const round = match_info.round;
const scores = match_info.scoresCsv;
const scores_data = scores.split("-")
if (!scores_data || scores_data.length != 2)
continue;
const player1 = match_info.player1Id;
const player2 = match_info.player2Id;
const match_txt = "[" + sign + "]组:\n [1号]" + name_list[player1] + " " + scores_data[0] + "\n [2号]" + name_list[player2] + " " + scores_data[1] + "\n";
if (!results[round])
results[round] = [];
results[round].push(match_txt);
}
console.log("Request completed. Outputing data.")
var player_text = "";
for (var k in name_list) {
player_text = player_text + name_list[k] + "\n";
}
fs.writeFileSync(output_path + "/player_list.txt", player_text);
for (var k in results) {
const round_data = results[k];
var text = "";
for (var k1 in round_data) {
text = text + round_data[k1];
}
fs.writeFileSync(output_path + "/match_" + k + ".txt", text);
}
console.log("Finished.")
}
})
}
})
......@@ -17,6 +17,8 @@ var moment = require('moment');
moment.locale('zh-cn');
var loadJSON = require('load-json-file').sync;
var auth = require('./ygopro-auth.js');
var constants = loadJSON('./data/constants.json');
var settings = loadJSON('./config/config.json');
......@@ -406,7 +408,7 @@ var packDatas = function () {
http.createServer(function (req, res) {
var u = url.parse(req.url, true);
if (u.query.password !== config.password) {
if (!auth.auth(u.query.username, u.query.password, "pre_dashboard", "pre_dashboard")) {
res.writeHead(403);
res.end("Auth Failed.");
return;
......@@ -464,4 +466,3 @@ http.createServer(function (req, res) {
}
}).listen(config.port);
This diff is collapsed.
This diff is collapsed.
......@@ -16,6 +16,8 @@ _.str = require('underscore.string');
_.mixin(_.str.exports());
var loadJSON = require('load-json-file').sync;
var auth = require('./ygopro-auth.js');
var settings = loadJSON('./config/config.json');
config=settings.modules.tournament_mode;
challonge_config=settings.modules.challonge;
......@@ -215,13 +217,18 @@ var receiveDecks = function(files) {
http.createServer(function (req, res) {
var u = url.parse(req.url, true);
if (u.query.password !== config.password) {
/*if (u.query.password !== config.password) {
res.writeHead(403);
res.end("Auth Failed.");
return;
}
}*/
if (u.pathname === '/api/upload_decks' && req.method.toLowerCase() == 'post') {
if (!auth.auth(u.query.username, u.query.password, "deck_dashboard_write", "upload_deck")) {
res.writeHead(403);
res.end("Auth Failed.");
return;
}
var form = new formidable.IncomingForm();
form.parse(req, function(err, fields, files) {
res.writeHead(200, {
......@@ -234,6 +241,11 @@ http.createServer(function (req, res) {
});
}
else if (u.pathname === '/api/msg') {
if (!auth.auth(u.query.username, u.query.password, "deck_dashboard_read", "login_deck_dashboard")) {
res.writeHead(403);
res.end("Auth Failed.");
return;
}
res.writeHead(200, {
"Access-Control-Allow-origin": "*",
"Content-Type": "text/event-stream",
......@@ -250,25 +262,50 @@ http.createServer(function (req, res) {
sendResponse("已连接。");
}
else if (u.pathname === '/api/get_bg') {
if (!auth.auth(u.query.username, u.query.password, "deck_dashboard_read", "login_deck_dashboard")) {
res.writeHead(403);
res.end("Auth Failed.");
return;
}
res.writeHead(200);
res.end(u.query.callback+'('+JSON.stringify(config.wallpapers[Math.floor(Math.random() * config.wallpapers.length)])+');');
}
else if (u.pathname === '/api/get_decks') {
if (!auth.auth(u.query.username, u.query.password, "deck_dashboard_read", "get_decks")) {
res.writeHead(403);
res.end("Auth Failed.");
return;
}
res.writeHead(200);
var decklist=getDecks();
res.end(u.query.callback+'('+JSON.stringify(decklist)+');');
}
else if (u.pathname === '/api/del_deck') {
if (!auth.auth(u.query.username, u.query.password, "deck_dashboard_write", "delete_deck")) {
res.writeHead(403);
res.end("Auth Failed.");
return;
}
res.writeHead(200);
var result=delDeck(u.query.msg);
res.end(u.query.callback+'("'+result+'");');
}
else if (u.pathname === '/api/clear_decks') {
if (!auth.auth(u.query.username, u.query.password, "deck_dashboard_write", "clear_decks")) {
res.writeHead(403);
res.end("Auth Failed.");
return;
}
res.writeHead(200);
clearDecks();
res.end(u.query.callback+'("已删除全部卡组。");');
}
else if (u.pathname === '/api/upload_to_challonge') {
if (!auth.auth(u.query.username, u.query.password, "deck_dashboard_write", "upload_to_challonge")) {
res.writeHead(403);
res.end("Auth Failed.");
return;
}
res.writeHead(200);
var result=UploadToChallonge();
res.end(u.query.callback+'("操作完成。");');
......@@ -279,4 +316,3 @@ http.createServer(function (req, res) {
}
}).listen(config.port);
......@@ -18,6 +18,8 @@ var moment = require('moment');
moment.locale('zh-cn');
var loadJSON = require('load-json-file').sync;
var auth = require('./ygopro-auth.js');
var constants = loadJSON('./data/constants.json');
var settings = loadJSON('./config/config.json');
......@@ -213,7 +215,7 @@ var pushHTMLs = function() {
http.createServer(function (req, res) {
var u = url.parse(req.url, true);
if (u.query.password !== config.password) {
if (!auth.auth(u.query.username, u.query.password, "update_dashboard", "update_dashboard")) {
res.writeHead(403);
res.end("Auth Failed.");
return;
......@@ -274,4 +276,3 @@ http.createServer(function (req, res) {
}
}).listen(config.port);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment