Commit efd9864a authored by 神楽坂玲奈's avatar 神楽坂玲奈

install

parent b0326c82
/ygopro/ *.tar.xz
/node_modules/ /node_modules/
/nbproject/ /nbproject/
......
...@@ -56,7 +56,6 @@ module.exports = function (grunt) { ...@@ -56,7 +56,6 @@ module.exports = function (grunt) {
outputDirectory: 'release', outputDirectory: 'release',
authors: 'MyCard', authors: 'MyCard',
exe: 'electron.exe', exe: 'electron.exe',
description: 'nyanya'
}/*, }/*,
ia32: { ia32: {
appDirectory: 'build/32', appDirectory: 'build/32',
......
'use strict';
const os = require('os');
const fs = require('fs');
const path = require('path');
const child_process = require('child_process');
const ini = require('ini');
const glob = require("glob");
const mkdirp = require('mkdirp');
const EventEmitter = require('events');
const eventemitter = new EventEmitter();
const electron = require('electron');
const app = electron.app;
const BrowserWindow = electron.BrowserWindow;
const data_path = app.getPath('userData');
const db_path = path.join(data_path, 'db.json');
const db = {apps: {}, local: {}};
try {
Object.assign(db, require(db_path));
} catch (error) {
}
db.version = app.getVersion();
db.platform = os.platform();
db.default_apps_path = path.join(data_path, 'apps');
var bundle;
try {
bundle = require('./bundle.json')
} catch (error) {
}
function save_db() {
fs.writeFile(db_path, JSON.stringify(db));
}
eventemitter.on('install', (app, options) => {
console.log(app, options);
if (db.local[app.id]) return;
db.apps[app.id] = app;
let local = db.local[app.id] = {
status: 'installing'
};
if (options.path) {
local.path = options.path;
} else {
local.path = path.join(db.default_apps_path, app.id);
}
eventemitter.emit('update', app, local, 'install-started');
mkdirp(local.path, ()=> {
let extract = child_process.spawn('tar', ['fx', app.id + '.tar.xz', '-C', local.path], {stdio: 'inherit'});
extract.on('exit', (code) => {
console.log(code);
if (code == 0) {
load(app, local, ()=> {
local.status = 'ready';
eventemitter.emit('update', app, local, 'install-successful');
});
} else {
delete db.local[app.id];
eventemitter.emit('update', app, local, 'install-failed');
eventemitter.emit('update', app, null);
}
});
})
});
eventemitter.on('action', function (app_id, action, options) {
var local = db.local[app_id];
Object.assign(local.files['system.conf'].content, options);
fs.writeFile(path.join(local.path, 'system.conf'), ini.stringify(local.files['system.conf'].content, {whitespace: true}), (error)=> {
if (error) return console.log(error);
for (let window of BrowserWindow.getAllWindows()) {
window.minimize()
}
let args = {'join': '-j', 'deck': '-d'}[action];
let main;
if (os.platform() == 'darwin') {
main = 'ygopro.app/Contents/MacOS/ygopro'
} else {
main = 'ygopro_vs.exe'
}
console.log(main, [args], {cwd: local.path});
let child = child_process.spawn(main, [args], {cwd: local.path, stdio: 'inherit'});
child.on('exit', ()=> {
for (let window of BrowserWindow.getAllWindows()) {
window.restore()
}
})
})
});
eventemitter.on('delete', (app_id, file) => {
fs.unlink(path.join(db.local[app_id].path, file));
delete db.local[app_id].files[file];
});
eventemitter.on('write', (app_id, file, data, merge) => {
let local = db.local[app_id];
if (file == 'system.conf') {
if (merge) {
Object.assign(local.files[file].content, data)
} else {
local.files[file].content = data
}
fs.writeFile(path.join(local.path, file), ini.stringify(local.files[file].content, {whitespace: true}))
}
//TODO: others
});
//fixme: refactoring
let pending = 1;
for (let app_id in db.local) {
pending++;
load(db.apps[app_id], db.local[app_id], done);
}
done();
function done() {
pending--;
if (pending == 0) {
start_server();
}
}
function start_server() {
const WebSocketServer = require('ws').Server;
const server = new WebSocketServer({host: '127.0.0.1', port: 9999});
server.on('connection', (connection) => {
connection.send(JSON.stringify({
event: 'init',
data: [db]
}));
if (bundle && Object.keys(db.apps).length == 0) {
connection.send(JSON.stringify({
event: 'bundle',
data: [bundle]
}));
}
connection.on('message', (message) => {
message = JSON.parse(message);
eventemitter.emit(message.event, ...message.data);
});
});
eventemitter.on('update', (app, local, resson)=> {
let message = JSON.stringify({event: 'update', data: [app, local, resson]});
for (let connection of server.clients) {
connection.send(message);
}
save_db();
})
}
function load(app, local, callback) {
let pending = 1;
let done = ()=> {
pending--;
if (pending == 0) {
callback();
}
};
if (app.files) {
local.files = {};
for (let pattern in app.files) {
pending++;
glob(pattern, {cwd: local.path}, (error, files)=> {
if (error)return done();
for (let file of files) {
if (app.files[pattern].content == 'ini') {
fs.readFile(path.join(local.path, file), 'utf8', (error, content)=> {
if (error)return done();
local.files[file] = {content: ini.parse(content)};
done()
})
} else {
local.files[file] = {};
done()
}
}
})
}
}
done()
}
[
{
"id": "ygopro",
"version": "1",
"locales": {
"zh-CN": {
"name": "YGOPro"
}
},
"files": {
"system.conf": {
"content": "ini"
},
"deck/*.ydk": {
"sync": true
},
"replay/*.yrp": {
},
"backup/replay/*.yrp": {
}
},
"actions": {
"darwin": {
"join": {
"execuate": "ygopro.app/Contents/MacOS/ygopro",
"args": [
"-j"
]
},
"deck": {
"execuate": "ygopro.app/Contents/MacOS/ygopro",
"args": [
"-d"
]
},
"replay": {
"execuate": "ygopro.app/Contents/MacOS/ygopro",
"args": [
"-r"
]
},
"single": {
"execuate": "ygopro.app/Contents/MacOS/ygopro",
"args": [
"-s"
]
}
}
},
"association": {
".ydk": "deck",
".deck": "deck",
".ydp": "replay"
}
}
]
\ No newline at end of file
...@@ -110,9 +110,9 @@ ...@@ -110,9 +110,9 @@
<div class="navbar-right">zh99998</div> <div class="navbar-right">zh99998</div>
</div> </div>
</nav> </nav>
<!--<webview id="ygopro" src="http://local.mycard.moe:3000/"></webview>-->
<webview id="store" src="http://mycard.moe/"></webview> <webview id="store" src="http://mycard.moe/"></webview>
<webview id="ygopro" src="http://mycard.moe/lobby/"></webview> <!-- fuck https https://plus.google.com/u/0/+%E7%A5%9E%E6%A5%BD%E5%9D%82%E7%8E%B2%E5%A5%88/posts/79g2y5JRB1Z --> <webview id="ygopro" src="http://local.mycard.moe:3000/"></webview>
<!--<webview id="ygopro" src="http://mycard.moe/lobby/"></webview>--> <!-- fuck https https://plus.google.com/u/0/+%E7%A5%9E%E6%A5%BD%E5%9D%82%E7%8E%B2%E5%A5%88/posts/79g2y5JRB1Z -->
<webview id="forum" src="https://forum.touhou.cc"></webview> <webview id="forum" src="https://forum.touhou.cc"></webview>
<script> <script>
......
...@@ -133,7 +133,7 @@ app.on('ready', function () { ...@@ -133,7 +133,7 @@ app.on('ready', function () {
}); });
//const ipcMain = require('electron').ipcMain; //const ipcMain = require('electron').ipcMain;
const ygopro = require('./ygopro'); const ygopro = require('./apps');
/*ipcMain.on('join', (event, args) => { /*ipcMain.on('join', (event, args) => {
ygopro.emit('run', args); ygopro.emit('run', args);
}); });
......
{ {
"name": "mycard", "name": "mycard",
"description":"a game platform", "description": "a game platform",
"version": "2.0.0", "version": "2.0.0",
"main": "main.js", "main": "main.js",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"repository": "github:mycard/mycard", "repository": "github:mycard/mycard",
"dependencies": { "dependencies": {
"glob": "^6.0.4",
"ini": "^1.3.4",
"mkdirp": "^0.5.1",
"ws": "^1.0.1" "ws": "^1.0.1"
}, },
"optionalDependencies": { "optionalDependencies": {
......
"use strict";
/**
* Created by zh99998 on 16/1/24.
*/
const child_process = require('child_process');
const http = require('http');
const querystring = require('querystring');
const url = require('url');
const fs = require('fs');
const path = require('path');
const electron = require('electron');
const BrowserWindow = electron.BrowserWindow;
const ygopro_directory = 'ygopro';
const ygopro_main = 'ygopro.app/Contents/MacOS/ygopro';
const ygopro_system_conf = path.join(ygopro_directory, 'system.conf');
const ygopro_decks = path.join(ygopro_directory, 'deck');
const EventEmitter = require('events');
const ygopro = new EventEmitter();
ygopro.on('start', function (system, args) {
fs.readFile(ygopro_system_conf, 'utf8', (error, conf)=> {
if (error) return console.log(error);
let options = {};
for (let line of conf.split("\n")) {
if (line.charAt(0) == '#') continue;
if (!line[1])continue;
line = line.split(' = ');
options[line[0]] = line[1];
}
Object.assign(options, system);
let result = [];
for (let key in options) {
result.push(key + " = " + options[key])
}
fs.writeFile(ygopro_system_conf, result.join("\n"), (error)=> {
if (error) return console.log(error);
if (args) {
for (let window of BrowserWindow.getAllWindows()) {
window.minimize()
}
let child = child_process.spawn(ygopro_main, [args], {cwd: ygopro_directory});
child.on('exit', ()=> {
for (let window of BrowserWindow.getAllWindows()) {
window.restore()
}
})
}
})
});
});
ygopro.on('delete', function (file) {
if (path.dirname(file) == 'deck' && path.extname(file) == '.ydk') {
fs.unlink(path.join(ygopro_directory, file));
let deck = path.basename(file, '.ydk');
for (let i in decks) {
if (decks[i].name === deck) decks.splice(i, 1);
}
} // reject others
});
module.exports = ygopro;
const system = {};
const decks = [];
let pending = 2;
fs.readFile(ygopro_system_conf, 'utf8', (error, file)=> {
if (error) return done();
for (let line of file.split("\n")) {
if (line.charAt(0) == '#') continue;
line = line.split(' = ');
if (!line[1])continue;
system[line[0]] = line[1];
}
done()
});
fs.readdir(ygopro_decks, (error, files)=> {
if (error) return done();
let deckfiles = [];
for (let filename of files) {
if (path.extname(filename) == '.ydk') {
deckfiles.push(filename);
}
}
for (let filename of deckfiles) {
let deck = {name: path.basename(filename, '.ydk'), cards: []};
pending++;
fs.stat(path.join(ygopro_decks, filename), (error, stats)=> {
if (error)return done();
deck.created_at = stats.birthtime;
deck.updated_at = stats.mtime;
fs.readFile(path.join(ygopro_decks, filename), 'utf8', (error, file)=> {
if (error)return done();
let side = false;
let cards = {};
for (let line of file.split("\n")) {
if (line.charAt(0) == '#') continue;
if (line.slice(0, 5) == '!side') {
for (let card_id in cards) {
deck.cards.push(cards[card_id]);
}
cards = {};
}
let id = parseInt(line);
if (!id)continue;
if (cards[id]) {
cards[id].count++;
} else {
cards[id] = {id: id, count: 1, side: side};
}
}
for (let card_id in cards) {
deck.cards.push(cards[card_id]);
}
decks.push(deck);
done()
})
})
}
done()
});
function done() {
pending--;
if (pending == 0) {
start_server();
}
}
function start_server() {
const WebSocketServer = require('ws').Server;
const server = new WebSocketServer({host: '127.0.0.1', port: 9999});
server.on('connection', (connection) => {
connection.send(JSON.stringify({
event: 'init',
data: {
system: system,
decks: decks
}
}));
connection.on('message', (message) => {
message = JSON.parse(message);
ygopro.emit(message.event, ...message.data);
});
});
}
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