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

数据库、成就、README

parent 5d71924e
...@@ -4,6 +4,18 @@ ...@@ -4,6 +4,18 @@
毛玉只是开发代号,不作为最终名称,可能会并入mycard 毛玉只是开发代号,不作为最终名称,可能会并入mycard
## 要解决的问题
* 找资源(本体、更新补丁、语言包)繁琐,尤其是过时资源
* 在中国大陆即使想购买正版也很难买到
* 独立游戏作者没有渠道发布游戏
* (需要联机的游戏)跨运营商互访困难、没有公网IP
* 需要手动下载安装vc++运行时、DirectX运行时等依赖项,这个并不是所有人都会的
* 有些游戏甚至要配置一下才能用,例如东方心绮楼需要玩家手动在目录下建立个network_history的文件才能进行联机;要起英文以外的profile名字必须手动改文件;要换头像必须手动改文件
* 存档和个人资料同步(例如非想天则玩家卡组)
* 有些游戏原生不支持某些平台,但是有办法能调教起来,例如东方大多数游戏可以用wine在Linux/OSX下运行
* 有些游戏系统需要依赖网络实现(例如成就),而游戏作者可能并不擅长这个
* 社交、战绩统计
## 功能列表 (发布之前) ## 功能列表 (发布之前)
* 用户登录 * 用户登录
* 聊天 * 聊天
...@@ -80,14 +92,64 @@ ...@@ -80,14 +92,64 @@
二进制文件可以在 http://test2.my-card.in/downloads/maotama/maotama_win32_binaries.7z 下载 二进制文件可以在 http://test2.my-card.in/downloads/maotama/maotama_win32_binaries.7z 下载
## 数据定义
应用
id --> 必填, 标识符,通常是英文简称,由小写字母、数字、下划线组成
category --> 必填, 应用类型
category: game --> 游戏,以及其他不方便归类的可执行程序
category: audio --> 音频,音乐等
category: video --> 视频,动画等
category: graphics --> 静态图片,漫画等
category: book --> FanBook、小说等
category: development --> 开发者相关,通常是运行时依赖项,例如 DirectX
name --> 必填, 应用名称 //TODO: i18n
network --> 如果应用需要反重力场功能,在这里填写网络相关信息
protocol --> 协议,必须为udp
port --> 默认端口
main --> 主程序文件名 //TODO: 跨平台
summary --> 应用介绍
download --> 必填, 下载信息
languages --> 语言的数组,语言是像zh-CN这样的字符串
mods --> 附加模块的数组. mods和dependencies的区别是,mods必须依赖于应用本体而存在,dependencies可以独立存在,可以为多个应用服务
name --> 对于type=language以外必填, 名称 //TODO: i18n
type --> 必填, 模块类型
type: language --> 语言包
type: dlc --> DLC
languages --> type=language时必填,语言的数组
override_main --> 覆盖应用的入口程序
main --> mod自己的入口程序
download --> 必填,下载信息
dependencies --> 相关资源
id --> 必填,id
type --> 必填,依赖类型
type: require --> 必需依赖 例如 DirectX //TODO: 跨平台
type: optional --> 可选依赖 例如 th123 -> th135
achievements --> 收集要素的数组
name --> 收集要素名称,例如 【成就】、【符卡】
type --> 必填,收集要素类型
type:unlock --> 解锁
items --> 必填,具体的收集要素项目的数组
icon --> 必填,图标的url,协议必须是http、https之一
name --> 必填,标题
description --> 介绍
下载信息
url --> 必填,协议必须是http、https、ftp之一
size --> 必填,文件大小,字节数
checksum --> 必填,md5校验码
## API ## API
* XMPP my-card.in * XMPP my-card.in
* XMPP聊天室 conference.my-card.in * XMPP聊天室 conference.my-card.in
* 以下全都为临时,开发用 * 以下全都为临时,开发用
* 用户认证 https://my-card.in/users/me.json?name=用户名&password=密码 * 用户认证 https://my-card.in/users/me.json?name=用户名&password=密码
* 反重力场 ws://122.0.65.69:10800/ * 反重力场 ws://122.0.65.69:10800/
* 资源列表 https://github.com/mycard/maotama/raw/master/apps.json * 应用列表 (本地app目录) apps.json
* 资源下载 http://test2.my-card.in/downloads/maotama/ * 应用元文件 (本地app目录) meta
## 相关技术 ## 相关技术
......
[
{
"id": "th135",
"category": "game",
"name": "东方心绮楼",
"network": {
"protocol": "udp",
"port": 10800
},
"main": "th135.exe",
"summary": "喵喵喵喵喵帕斯 \nnyanpass nyanpass",
"download": {
"url": "http://test2.my-card.in/downloads/maotama/th135_1.33.7z",
"size": 313177031,
"checksum": "ab3c7f4646e080fb88959978865ebf24"
},
"languages": ["ja-JP"],
"mods": [
{
"override_main": "th135c.exe",
"type": "language",
"languages": ["zh-CN"],
"download": {
"url": "http://test2.my-card.in/downloads/maotama/th135_lang_zh-CN_1.33.7z",
"size": 74749190,
"checksum": "49111c67d941e30384251a2026ba67ba"
}
}
]
},
{
"id": "th123",
"category": "game",
"name": "东方非想天则",
"network": {
"protocol": "udp",
"port": 10800
},
"summary": "",
"download": {
"url": "http://test2.my-card.in/downloads/maotama/th123_1.10a.7z",
"size": 250272482,
"checksum": "027a358a7ac014f725ebb8659f1caa6f"
},
"main": "th123.exe",
"languages": ["ja-JP"],
"mods": [
{
"type": "language",
"languages": ["zh-CN"],
"override_main": "th123_beta.exe",
"download": {
"url": "http://test2.my-card.in/downloads/maotama/th123_lang_zh-CN_1.10a.7z",
"size": 7711357,
"checksum": "4e947e2cded2ed21cf691d6ad3bdd04b"
}
}
],
"dependencies": [
{
"id": "th105",
"type": "optional"
}
]
},
{
"id": "th105",
"category": "game",
"name": "东方绯想天",
"network": {
"protocol": "udp",
"port": 10800
},
"summary": "0 0",
"download": {
"url": "http://test2.my-card.in/downloads/maotama/th105_1.06a.7z",
"size": 274941544,
"checksum": "4cd0360e11847ddd7645017769cad73e"
},
"main": "th105.exe",
"languages": ["ja-JP"],
"mods": [
{
"type": "language",
"languages": ["zh-CN"],
"download": {
"url": "http://test2.my-card.in/downloads/maotama/th105_lang_zh-CN_1.06a.7z",
"size": 8809810,
"checksum": "26fb9f83fe957e266377e70fe91aee3b"
}
}
],
"related": [
{
"id": "th105",
"type": "recommended"
}
]
},
{
"id": "leq",
"category": "game",
"name": "萝莉的远征Q:偷菜大战",
"summary": "六一,送大家一个好礼物! \n也是华音的生日!",
"download": {
"url": "http://test2.my-card.in/downloads/maotama/leq.7z",
"size": 2210749,
"checksum": "8550d57175cd1e0a66fae2c406981121"
},
"icon": "meta/leq/icon.png",
"main": "game.exe",
"languages": ["zh-CN"],
"achievements": [
{
"name": "成就",
"type": "unlock",
"items": [
{
"icon": "meta/leq/1.png",
"name": "第一关",
"description": "喵喵喵喵喵帕斯"
},
{
"icon": "meta/leq/2.png",
"name": "第二关",
"description": "喵喵喵喵喵帕斯"
},
{
"icon": "meta/leq/3.png",
"name": "第三关",
"description": "喵喵喵喵喵帕斯"
},
{
"icon": "meta/leq/4.png",
"name": "第四关",
"description": "喵喵喵喵喵帕斯"
},
{
"icon": "meta/leq/5.png",
"name": "第五关",
"description": "喵喵喵喵喵帕斯"
},
{
"icon": "meta/leq/6.png",
"name": "第六关",
"description": "喵喵喵喵喵帕斯"
},
{
"icon": "meta/leq/7.png",
"name": "第七关",
"description": "喵喵喵喵喵帕斯"
},
{
"icon": "meta/leq/8.png",
"name": "第八关",
"description": "Game Over"
}
]
}
]
}
]
\ No newline at end of file
...@@ -107,6 +107,7 @@ ...@@ -107,6 +107,7 @@
<script src="lib/angular/angular.min.js"></script> <script src="lib/angular/angular.min.js"></script>
<script src="lib/angular/angular-route.min.js"></script> <script src="lib/angular/angular-route.min.js"></script>
<script src="lib/angular/angular-sanitize.min.js"></script>
<script src="js/filters.js"></script> <script src="js/filters.js"></script>
<script src="js/services.js"></script> <script src="js/services.js"></script>
<script src="js/directives.js"></script> <script src="js/directives.js"></script>
......
maotama = angular.module 'maotama', [ maotama = angular.module 'maotama', [
'ngRoute', 'ngRoute',
'ngSanitize',
'maotama.filters', 'maotama.filters',
'maotama.services', 'maotama.services',
'maotama.directives', 'maotama.directives',
...@@ -11,6 +12,6 @@ maotama.config ['$routeProvider',($routeProvider)-> ...@@ -11,6 +12,6 @@ maotama.config ['$routeProvider',($routeProvider)->
.when '/apps/:app_id', .when '/apps/:app_id',
templateUrl: 'partials/app_show.html', templateUrl: 'partials/app_show.html',
controller: 'AppsShowController' controller: 'AppsShowController'
.otherwise #.otherwise
redirectTo:'/apps/th123' # redirectTo:'/apps/th123'
] ]
\ No newline at end of file
...@@ -2,15 +2,13 @@ ...@@ -2,15 +2,13 @@
(function() { (function() {
var maotama; var maotama;
maotama = angular.module('maotama', ['ngRoute', 'maotama.filters', 'maotama.services', 'maotama.directives', 'maotama.controllers']); maotama = angular.module('maotama', ['ngRoute', 'ngSanitize', 'maotama.filters', 'maotama.services', 'maotama.directives', 'maotama.controllers']);
maotama.config([ maotama.config([
'$routeProvider', function($routeProvider) { '$routeProvider', function($routeProvider) {
return $routeProvider.when('/apps/:app_id', { return $routeProvider.when('/apps/:app_id', {
templateUrl: 'partials/app_show.html', templateUrl: 'partials/app_show.html',
controller: 'AppsShowController' controller: 'AppsShowController'
}).otherwise({
redirectTo: '/apps/th123'
}); });
} }
]); ]);
......
...@@ -6,5 +6,5 @@ ...@@ -6,5 +6,5 @@
"app.coffee" "app.coffee"
], ],
"names": [], "names": [],
"mappings": ";AAAA;AAAA,MAAA,OAAA;;AAAA,EAAA,OAAA,GAAU,OAAO,CAAC,MAAR,CAAe,SAAf,EAA0B,CAClC,SADkC,EAElC,iBAFkC,EAGlC,kBAHkC,EAIlC,oBAJkC,EAKlC,qBALkC,CAA1B,CAAV,CAAA;;AAAA,EAQA,OAAO,CAAC,MAAR,CAAe;IAAC,gBAAD,EAAkB,SAAC,cAAD,GAAA;aAC/B,cACA,CAAC,IADD,CACM,eADN,EAEI;AAAA,QAAA,WAAA,EAAa,wBAAb;AAAA,QACA,UAAA,EAAY,oBADZ;OAFJ,CAIA,CAAC,SAJD,CAKI;AAAA,QAAA,UAAA,EAAW,aAAX;OALJ,EAD+B;IAAA,CAAlB;GAAf,CARA,CAAA;AAAA" "mappings": ";AAAA;AAAA,MAAA,OAAA;;AAAA,EAAA,OAAA,GAAU,OAAO,CAAC,MAAR,CAAe,SAAf,EAA0B,CAClC,SADkC,EAElC,YAFkC,EAGlC,iBAHkC,EAIlC,kBAJkC,EAKlC,oBALkC,EAMlC,qBANkC,CAA1B,CAAV,CAAA;;AAAA,EASA,OAAO,CAAC,MAAR,CAAe;IAAC,gBAAD,EAAkB,SAAC,cAAD,GAAA;aAC/B,cACA,CAAC,IADD,CACM,eADN,EAEI;AAAA,QAAA,WAAA,EAAa,wBAAb;AAAA,QACA,UAAA,EAAY,oBADZ;OAFJ,EAD+B;IAAA,CAAlB;GAAf,CATA,CAAA;AAAA"
} }
\ No newline at end of file
path = require 'path' path = require 'path'
fs = require 'fs' fs = require 'fs'
child_process = require 'child_process' child_process = require 'child_process'
crypto = require('crypto'); crypto = require 'crypto'
mkdirp = require 'mkdirp' mkdirp = require 'mkdirp'
rmdir = require 'rmdir'
gui = require 'nw.gui' gui = require 'nw.gui'
Datastore = require('nw_nedb') Datastore = require 'nw_nedb'
db = new Datastore({ filename: path.join(gui.App.dataPath, 'apps.db'), autoload: true }); db =
apps: new Datastore({ filename: path.join(gui.App.dataPath, 'apps.db'), autoload: true })
local: new Datastore({ filename: path.join(gui.App.dataPath, 'local.db'), autoload: true })
angular.module('maotama.controllers', []) angular.module('maotama.controllers', [])
.controller 'AppsListController', ($scope)-> .controller 'AppsListController', ($scope, $http)->
db.find {}, (err, docs)=> $scope.orderProp = 'id';
throw err if err $http.get('apps.json').success (data)->
$scope.apps = docs console.log data
$scope.$digest(); db.apps.remove {}, { multi: true }, (err, numRemoved)->
throw err if err
db.apps.insert data, (err, newDocs)->
throw err if err
$scope.apps = data
$scope.$digest()
.controller 'AppsShowController', ['$scope', '$routeParams', ($scope, $routeParams)-> .controller 'AppsShowController', ['$scope', '$routeParams', ($scope, $routeParams)->
db.findOne {id: $routeParams.app_id}, (err, doc)-> db.apps.findOne {id: $routeParams.app_id}, (err, doc)->
throw err if err throw err if err
$scope.app = doc; $scope.app = doc
console.log $scope.app $scope.runtime =
$scope.app.default_installation_path = path.join process.cwd(), 'apps', $scope.app.id running: false
$scope.app.extra_languages = {} installing: {}
for lang, download of $scope.app.languages $scope.default_installation_path = path.join process.cwd(), 'apps', $scope.app.id
console.assert $scope.app.download.url
console.assert $scope.app.download.size db.local.findOne {id: $routeParams.app_id}, (err, doc)->
if download != true $scope.local = doc ? {}
$scope.app.has_extra_languages = true $scope.$digest();
$scope.app.extra_languages[lang] = download
$scope.installing = {};
$scope.$digest();
$scope.add = (installation)-> $scope.add = (installation)->
$scope.app.installation = path.dirname installation $scope.local.installation = path.dirname installation
db.update { db.local.update {
id: $scope.app.id id: $scope.app.id
}, { }, {
$set: { $set: {
installation: $scope.app.installation installation: $scope.local.installation
} }
}, {
upsert: true
}, (err, numReplaced, newDoc)-> }, (err, numReplaced, newDoc)->
throw err if err throw err if err
$scope.$digest(); $scope.$digest();
$scope.install = ()-> $scope.install = ()->
$scope.installing[$scope.app.id] =
$scope.runtime.installing[$scope.app.id] =
process: 0 process: 0
label: '正在连接' label: '正在连接'
mkdirp path.join(process.cwd(), 'cache'), (err)-> mkdirp path.join(process.cwd(), 'cache'), (err)->
...@@ -58,22 +64,23 @@ angular.module('maotama.controllers', []) ...@@ -58,22 +64,23 @@ angular.module('maotama.controllers', [])
console.log data console.log data
#[#06c774 35MiB/298MiB(11%) CN:1 DL:62MiB ETA:4s] #[#06c774 35MiB/298MiB(11%) CN:1 DL:62MiB ETA:4s]
#[#d1b179 752KiB/298MiB(0%) CN:1 DL:109KiB ETA:46m17s] #[#d1b179 752KiB/298MiB(0%) CN:1 DL:109KiB ETA:46m17s]
#[#4dd4a5 592KiB/298MiB(0%) CN:1 DL:43KiB ETA:1h57m19s]
if matches = data.match(/\[(?:#\w+ )?([\w\.]+)\/([\w\.]+)\((\d+)%\) CN:(\d+) DL:([\w\.]+) ETA:(\w+)\]/) if matches = data.match(/\[(?:#\w+ )?([\w\.]+)\/([\w\.]+)\((\d+)%\) CN:(\d+) DL:([\w\.]+) ETA:(\w+)\]/)
[d, downloaded, total, progress, connections, speed, eta] = matches [d, downloaded, total, progress, connections, speed, eta] = matches
$scope.installing[$scope.app.id].progress = progress $scope.runtime.installing[$scope.app.id].progress = progress
$scope.installing[$scope.app.id].label = "#{progress}% #{speed}/s" $scope.runtime.installing[$scope.app.id].label = "#{progress}% #{speed}/s"
$scope.$digest(); $scope.$digest();
aria2c.stderr.on 'data', (data)-> aria2c.stderr.on 'data', (data)->
console.log 'err: ', data console.log 'err: ', data
aria2c.on 'close', (code)-> aria2c.on 'close', (code)->
if code != 0 if code != 0
window.LOCAL_NW.desktopNotifications.notify "TODO://icon", $scope.app.name, "下载失败, 错误: #{code}" window.LOCAL_NW.desktopNotifications.notify $scope.app.icon, $scope.app.name, "下载失败, 错误: #{code}"
delete $scope.installing[$scope.app.id] delete $scope.runtime.installing[$scope.app.id]
$scope.$digest(); $scope.$digest();
else else
$scope.installing[$scope.app.id].progress = 100 $scope.runtime.installing[$scope.app.id].progress = 100
$scope.installing[$scope.app.id].label = '正在安装' $scope.runtime.installing[$scope.app.id].label = '正在安装'
$scope.$digest(); $scope.$digest();
downloaded = "cache/#{path.basename($scope.app.download.url)}"; downloaded = "cache/#{path.basename($scope.app.download.url)}";
...@@ -86,8 +93,8 @@ angular.module('maotama.controllers', []) ...@@ -86,8 +93,8 @@ angular.module('maotama.controllers', [])
file.on 'end', ()-> file.on 'end', ()->
if checksum.digest('hex') != $scope.app.download.checksum if checksum.digest('hex') != $scope.app.download.checksum
window.LOCAL_NW.desktopNotifications.notify "TODO://icon", $scope.app.name, "校验错误" window.LOCAL_NW.desktopNotifications.notify $scope.app.icon, $scope.app.name, "校验错误"
delete $scope.installing[$scope.app.id] delete $scope.runtime.installing[$scope.app.id]
$scope.$digest(); $scope.$digest();
else else
p = path.join "apps/#{$scope.app.id}" p = path.join "apps/#{$scope.app.id}"
...@@ -103,76 +110,44 @@ angular.module('maotama.controllers', []) ...@@ -103,76 +110,44 @@ angular.module('maotama.controllers', [])
console.log 'err: ', data console.log 'err: ', data
p7zip.on 'close', (code)-> p7zip.on 'close', (code)->
if code != 0 if code != 0
window.LOCAL_NW.desktopNotifications.notify "TODO://icon", $scope.app.name, "安装失败, 错误: #{code}" window.LOCAL_NW.desktopNotifications.notify $scope.app.icon, $scope.app.name, "安装失败, 错误: #{code}"
delete $scope.installing[$scope.app.id] delete $scope.runtime.installing[$scope.app.id]
$scope.$digest(); $scope.$digest();
else else
delete $scope.installing[$scope.app.id] delete $scope.runtime.installing[$scope.app.id]
window.LOCAL_NW.desktopNotifications.notify "TODO://icon", $scope.app.name, '安装完成' window.LOCAL_NW.desktopNotifications.notify $scope.app.icon, $scope.app.name, '安装完成'
$scope.add path.join(p, $scope.app.main) $scope.add path.join(p, $scope.app.main)
$scope.uninstall = ()->
$scope.runtime.uninstalling = true
db.local.remove {
id: $scope.app.id
}, (err, numRemoved)->
throw err if err
rmdir $scope.local.installation, ( err, dirs, files )->
console.log dirs
console.log files
console.log 'all files are removed'
$scope.local = {}
$scope.$digest()
$scope.run = ()-> $scope.run = ()->
console.log $scope.app $scope.runtime.running = true
$scope.app.running = true game = child_process.spawn $scope.app.main, [],
child_process.execFile $scope.app.main, cwd: $scope.local.installation
cwd: $scope.app.installation game.stdout.setEncoding('utf8');
, (error, stdout, stderr)-> game.stdout.on 'data', (data)->
throw error if error console.log data
$scope.app.running = false if matches = data.match /<maotama>(.+)<\/maotama>/
for command in $(matches[1])
switch command.tagName
when 'ACHIEVEMENT'
achievement = $scope.app.achievements[$(command).attr('type')]
achievement_item = achievement.items[$(command).attr('id')]
window.LOCAL_NW.desktopNotifications.notify achievement_item.icon, "获得#{achievement.name}: #{achievement_item.name}", achievement_item.description
else
window.LOCAL_NW.desktopNotifications.notify $scope.app.icon, "unknown command", matches[1]
game.on 'close', (code)->
$scope.runtime.running = false
$scope.$digest(); $scope.$digest();
] ]
if false #for debug
db.remove {}, { multi: true }, (err, numRemoved)->
throw err if err
db.insert [{
"id":"th135",
"category":"game",
"name":"东方心绮楼",
"network":{
"proto":"udp",
"port":10800
},
"main":"th135.exe",
"summary":"喵喵喵喵喵帕斯
nyanpass nyanpass"
"download": {
"url": "http://test2.my-card.in/downloads/maotama/th135_1.33.7z"
"size": 313177031
"checksum":"ab3c7f4646e080fb88959978865ebf24"
}
"main": 'th135.exe'
"languages": {
"ja-JP": true
"zh-CN": {
url: "http://test2.my-card.in/downloads/maotama/th135_lang_zh-CN_1.33.7z"
size: 74749190
checksum: "49111c67d941e30384251a2026ba67ba"
}
}
},{
"id":"th123",
"category":"game",
"name":"东方非想天则",
"network":{
"proto":"udp",
"port":10800
},
"summary":"",
"download": {
url: "http://test2.my-card.in/downloads/maotama/th123_1.10a.7z"
"size": 250272482
"checksum": "027a358a7ac014f725ebb8659f1caa6f"
},
"main": 'th123.exe'
"languages": {
"ja-JP": true
}
}], (err, newDocs)->
throw err if err
console.log newDocs
\ No newline at end of file
// Generated by CoffeeScript 1.7.1 // Generated by CoffeeScript 1.7.1
(function() { (function() {
var Datastore, child_process, crypto, db, fs, gui, mkdirp, path; var Datastore, child_process, crypto, db, fs, gui, mkdirp, path, rmdir;
path = require('path'); path = require('path');
...@@ -12,59 +12,73 @@ ...@@ -12,59 +12,73 @@
mkdirp = require('mkdirp'); mkdirp = require('mkdirp');
rmdir = require('rmdir');
gui = require('nw.gui'); gui = require('nw.gui');
Datastore = require('nw_nedb'); Datastore = require('nw_nedb');
db = new Datastore({ db = {
filename: path.join(gui.App.dataPath, 'apps.db'), apps: new Datastore({
autoload: true filename: path.join(gui.App.dataPath, 'apps.db'),
}); autoload: true
}),
local: new Datastore({
filename: path.join(gui.App.dataPath, 'local.db'),
autoload: true
})
};
angular.module('maotama.controllers', []).controller('AppsListController', function($scope) { angular.module('maotama.controllers', []).controller('AppsListController', function($scope, $http) {
return db.find({}, (function(_this) { $scope.orderProp = 'id';
return function(err, docs) { return $http.get('apps.json').success(function(data) {
console.log(data);
return db.apps.remove({}, {
multi: true
}, function(err, numRemoved) {
if (err) { if (err) {
throw err; throw err;
} }
$scope.apps = docs; return db.apps.insert(data, function(err, newDocs) {
return $scope.$digest(); if (err) {
}; throw err;
})(this)); }
$scope.apps = data;
return $scope.$digest();
});
});
});
}).controller('AppsShowController', [ }).controller('AppsShowController', [
'$scope', '$routeParams', function($scope, $routeParams) { '$scope', '$routeParams', function($scope, $routeParams) {
db.findOne({ db.apps.findOne({
id: $routeParams.app_id id: $routeParams.app_id
}, function(err, doc) { }, function(err, doc) {
var download, lang, _ref;
if (err) { if (err) {
throw err; throw err;
} }
$scope.app = doc; $scope.app = doc;
console.log($scope.app); $scope.runtime = {
$scope.app.default_installation_path = path.join(process.cwd(), 'apps', $scope.app.id); running: false,
$scope.app.extra_languages = {}; installing: {}
_ref = $scope.app.languages; };
for (lang in _ref) { $scope.default_installation_path = path.join(process.cwd(), 'apps', $scope.app.id);
download = _ref[lang]; return db.local.findOne({
console.assert($scope.app.download.url); id: $routeParams.app_id
console.assert($scope.app.download.size); }, function(err, doc) {
if (download !== true) { $scope.local = doc != null ? doc : {};
$scope.app.has_extra_languages = true; return $scope.$digest();
$scope.app.extra_languages[lang] = download; });
}
}
$scope.installing = {};
return $scope.$digest();
}); });
$scope.add = function(installation) { $scope.add = function(installation) {
$scope.app.installation = path.dirname(installation); $scope.local.installation = path.dirname(installation);
return db.update({ return db.local.update({
id: $scope.app.id id: $scope.app.id
}, { }, {
$set: { $set: {
installation: $scope.app.installation installation: $scope.local.installation
} }
}, {
upsert: true
}, function(err, numReplaced, newDoc) { }, function(err, numReplaced, newDoc) {
if (err) { if (err) {
throw err; throw err;
...@@ -73,7 +87,7 @@ ...@@ -73,7 +87,7 @@
}); });
}; };
$scope.install = function() { $scope.install = function() {
$scope.installing[$scope.app.id] = { $scope.runtime.installing[$scope.app.id] = {
process: 0, process: 0,
label: '正在连接' label: '正在连接'
}; };
...@@ -90,8 +104,8 @@ ...@@ -90,8 +104,8 @@
console.log(data); console.log(data);
if (matches = data.match(/\[(?:#\w+ )?([\w\.]+)\/([\w\.]+)\((\d+)%\) CN:(\d+) DL:([\w\.]+) ETA:(\w+)\]/)) { if (matches = data.match(/\[(?:#\w+ )?([\w\.]+)\/([\w\.]+)\((\d+)%\) CN:(\d+) DL:([\w\.]+) ETA:(\w+)\]/)) {
d = matches[0], downloaded = matches[1], total = matches[2], progress = matches[3], connections = matches[4], speed = matches[5], eta = matches[6]; d = matches[0], downloaded = matches[1], total = matches[2], progress = matches[3], connections = matches[4], speed = matches[5], eta = matches[6];
$scope.installing[$scope.app.id].progress = progress; $scope.runtime.installing[$scope.app.id].progress = progress;
$scope.installing[$scope.app.id].label = "" + progress + "% " + speed + "/s"; $scope.runtime.installing[$scope.app.id].label = "" + progress + "% " + speed + "/s";
return $scope.$digest(); return $scope.$digest();
} }
}); });
...@@ -101,12 +115,12 @@ ...@@ -101,12 +115,12 @@
return aria2c.on('close', function(code) { return aria2c.on('close', function(code) {
var checksum, downloaded, file; var checksum, downloaded, file;
if (code !== 0) { if (code !== 0) {
window.LOCAL_NW.desktopNotifications.notify("TODO://icon", $scope.app.name, "下载失败, 错误: " + code); window.LOCAL_NW.desktopNotifications.notify($scope.app.icon, $scope.app.name, "下载失败, 错误: " + code);
delete $scope.installing[$scope.app.id]; delete $scope.runtime.installing[$scope.app.id];
return $scope.$digest(); return $scope.$digest();
} else { } else {
$scope.installing[$scope.app.id].progress = 100; $scope.runtime.installing[$scope.app.id].progress = 100;
$scope.installing[$scope.app.id].label = '正在安装'; $scope.runtime.installing[$scope.app.id].label = '正在安装';
$scope.$digest(); $scope.$digest();
downloaded = "cache/" + (path.basename($scope.app.download.url)); downloaded = "cache/" + (path.basename($scope.app.download.url));
checksum = crypto.createHash('md5'); checksum = crypto.createHash('md5');
...@@ -117,8 +131,8 @@ ...@@ -117,8 +131,8 @@
return file.on('end', function() { return file.on('end', function() {
var p; var p;
if (checksum.digest('hex') !== $scope.app.download.checksum) { if (checksum.digest('hex') !== $scope.app.download.checksum) {
window.LOCAL_NW.desktopNotifications.notify("TODO://icon", $scope.app.name, "校验错误"); window.LOCAL_NW.desktopNotifications.notify($scope.app.icon, $scope.app.name, "校验错误");
delete $scope.installing[$scope.app.id]; delete $scope.runtime.installing[$scope.app.id];
return $scope.$digest(); return $scope.$digest();
} else { } else {
p = path.join("apps/" + $scope.app.id); p = path.join("apps/" + $scope.app.id);
...@@ -139,12 +153,12 @@ ...@@ -139,12 +153,12 @@
}); });
return p7zip.on('close', function(code) { return p7zip.on('close', function(code) {
if (code !== 0) { if (code !== 0) {
window.LOCAL_NW.desktopNotifications.notify("TODO://icon", $scope.app.name, "安装失败, 错误: " + code); window.LOCAL_NW.desktopNotifications.notify($scope.app.icon, $scope.app.name, "安装失败, 错误: " + code);
delete $scope.installing[$scope.app.id]; delete $scope.runtime.installing[$scope.app.id];
return $scope.$digest(); return $scope.$digest();
} else { } else {
delete $scope.installing[$scope.app.id]; delete $scope.runtime.installing[$scope.app.id];
window.LOCAL_NW.desktopNotifications.notify("TODO://icon", $scope.app.name, '安装完成'); window.LOCAL_NW.desktopNotifications.notify($scope.app.icon, $scope.app.name, '安装完成');
return $scope.add(path.join(p, $scope.app.main)); return $scope.add(path.join(p, $scope.app.main));
} }
}); });
...@@ -155,82 +169,59 @@ ...@@ -155,82 +169,59 @@
}); });
}); });
}; };
$scope.uninstall = function() {
$scope.runtime.uninstalling = true;
return db.local.remove({
id: $scope.app.id
}, function(err, numRemoved) {
if (err) {
throw err;
}
return rmdir($scope.local.installation, function(err, dirs, files) {
console.log(dirs);
console.log(files);
console.log('all files are removed');
$scope.local = {};
return $scope.$digest();
});
});
};
return $scope.run = function() { return $scope.run = function() {
console.log($scope.app); var game;
$scope.app.running = true; $scope.runtime.running = true;
return child_process.execFile($scope.app.main, { game = child_process.spawn($scope.app.main, [], {
cwd: $scope.app.installation cwd: $scope.local.installation
}, function(error, stdout, stderr) { });
if (error) { game.stdout.setEncoding('utf8');
throw error; game.stdout.on('data', function(data) {
var achievement, achievement_item, command, matches, _i, _len, _ref, _results;
console.log(data);
if (matches = data.match(/<maotama>(.+)<\/maotama>/)) {
_ref = $(matches[1]);
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
command = _ref[_i];
switch (command.tagName) {
case 'ACHIEVEMENT':
achievement = $scope.app.achievements[$(command).attr('type')];
achievement_item = achievement.items[$(command).attr('id')];
_results.push(window.LOCAL_NW.desktopNotifications.notify(achievement_item.icon, "获得" + achievement.name + ": " + achievement_item.name, achievement_item.description));
break;
default:
_results.push(window.LOCAL_NW.desktopNotifications.notify($scope.app.icon, "unknown command", matches[1]));
}
}
return _results;
} }
$scope.app.running = false; });
return game.on('close', function(code) {
$scope.runtime.running = false;
return $scope.$digest(); return $scope.$digest();
}); });
}; };
} }
]); ]);
if (false) {
db.remove({}, {
multi: true
}, function(err, numRemoved) {
if (err) {
throw err;
}
return db.insert([
{
"id": "th135",
"category": "game",
"name": "东方心绮楼",
"network": {
"proto": "udp",
"port": 10800
},
"main": "th135.exe",
"summary": "喵喵喵喵喵帕斯 nyanpass nyanpass",
"download": {
"url": "http://test2.my-card.in/downloads/maotama/th135_1.33.7z",
"size": 313177031,
"checksum": "ab3c7f4646e080fb88959978865ebf24"
},
"main": 'th135.exe',
"languages": {
"ja-JP": true,
"zh-CN": {
url: "http://test2.my-card.in/downloads/maotama/th135_lang_zh-CN_1.33.7z",
size: 74749190,
checksum: "49111c67d941e30384251a2026ba67ba"
}
}
}, {
"id": "th123",
"category": "game",
"name": "东方非想天则",
"network": {
"proto": "udp",
"port": 10800
},
"summary": "",
"download": {
url: "http://test2.my-card.in/downloads/maotama/th123_1.10a.7z",
"size": 250272482,
"checksum": "027a358a7ac014f725ebb8659f1caa6f"
},
"main": 'th123.exe',
"languages": {
"ja-JP": true
}
}
], function(err, newDocs) {
if (err) {
throw err;
}
return console.log(newDocs);
});
});
}
}).call(this); }).call(this);
//# sourceMappingURL=controllers.map //# sourceMappingURL=controllers.map
...@@ -6,5 +6,5 @@ ...@@ -6,5 +6,5 @@
"controllers.coffee" "controllers.coffee"
], ],
"names": [], "names": [],
"mappings": "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" "mappings": "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"
} }
\ No newline at end of file
languages = require './js/languages.json' languages = require './js/languages.json'
humanize = require 'humanize' humanize = require 'humanize'
markdown = require( "markdown" ).markdown;
angular.module('maotama.filters', []) angular.module('maotama.filters', [])
.filter 'language_translate', ()-> .filter 'language_translate', ()->
...@@ -7,3 +9,6 @@ angular.module('maotama.filters', []) ...@@ -7,3 +9,6 @@ angular.module('maotama.filters', [])
languages[input] languages[input]
.filter 'filesize', ()-> .filter 'filesize', ()->
humanize.filesize humanize.filesize
.filter 'markdown', ()->
(input)->
markdown.toHTML(input) if input
\ No newline at end of file
// Generated by CoffeeScript 1.7.1 // Generated by CoffeeScript 1.7.1
(function() { (function() {
var humanize, languages; var humanize, languages, markdown;
languages = require('./js/languages.json'); languages = require('./js/languages.json');
humanize = require('humanize'); humanize = require('humanize');
markdown = require("markdown").markdown;
angular.module('maotama.filters', []).filter('language_translate', function() { angular.module('maotama.filters', []).filter('language_translate', function() {
return function(input) { return function(input) {
return languages[input]; return languages[input];
}; };
}).filter('filesize', function() { }).filter('filesize', function() {
return humanize.filesize; return humanize.filesize;
}).filter('markdown', function() {
return function(input) {
if (input) {
return markdown.toHTML(input);
}
};
}); });
}).call(this); }).call(this);
......
...@@ -6,5 +6,5 @@ ...@@ -6,5 +6,5 @@
"filters.coffee" "filters.coffee"
], ],
"names": [], "names": [],
"mappings": ";AAAA;AAAA,MAAA,mBAAA;;AAAA,EAAA,SAAA,GAAY,OAAA,CAAQ,qBAAR,CAAZ,CAAA;;AAAA,EACA,QAAA,GAAW,OAAA,CAAQ,UAAR,CADX,CAAA;;AAAA,EAGA,OAAO,CAAC,MAAR,CAAe,iBAAf,EAAkC,EAAlC,CACA,CAAC,MADD,CACQ,oBADR,EAC8B,SAAA,GAAA;WAC5B,SAAC,KAAD,GAAA;aACE,SAAU,CAAA,KAAA,EADZ;IAAA,EAD4B;EAAA,CAD9B,CAIA,CAAC,MAJD,CAIQ,UAJR,EAIoB,SAAA,GAAA;WAChB,QAAQ,CAAC,SADO;EAAA,CAJpB,CAHA,CAAA;AAAA" "mappings": ";AAAA;AAAA,MAAA,6BAAA;;AAAA,EAAA,SAAA,GAAY,OAAA,CAAQ,qBAAR,CAAZ,CAAA;;AAAA,EACA,QAAA,GAAW,OAAA,CAAQ,UAAR,CADX,CAAA;;AAAA,EAEA,QAAA,GAAW,OAAA,CAAS,UAAT,CAAqB,CAAC,QAFjC,CAAA;;AAAA,EAKA,OAAO,CAAC,MAAR,CAAe,iBAAf,EAAkC,EAAlC,CACA,CAAC,MADD,CACQ,oBADR,EAC8B,SAAA,GAAA;WAC5B,SAAC,KAAD,GAAA;aACE,SAAU,CAAA,KAAA,EADZ;IAAA,EAD4B;EAAA,CAD9B,CAIA,CAAC,MAJD,CAIQ,UAJR,EAIoB,SAAA,GAAA;WAChB,QAAQ,CAAC,SADO;EAAA,CAJpB,CAMA,CAAC,MAND,CAMQ,UANR,EAMoB,SAAA,GAAA;WAChB,SAAC,KAAD,GAAA;AACE,MAAA,IAA0B,KAA1B;eAAA,QAAQ,CAAC,MAAT,CAAgB,KAAhB,EAAA;OADF;IAAA,EADgB;EAAA,CANpB,CALA,CAAA;AAAA"
} }
\ No newline at end of file
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
This diff was suppressed by a .gitattributes entry.
<h1 class="page-header">{{app.name}} <h1 class="page-header">{{app.name}}
<button id="app_play" type="button" class="btn btn-default" ng-if="app.installation" ng-click="run()" ng-disabled="app.running"> <button id="app_play" type="button" class="btn btn-default" ng-if="local.installation" ng-click="run()" ng-disabled="runtime.running">
<span class="glyphicon glyphicon-play"></span> 开始 <span class="glyphicon glyphicon-play"></span> 开始
</button> </button>
<button id="app_install" type="button" class="btn btn-default" ng-if="!app.installation" data-toggle="modal" data-target="#app_install_modal"> <button id="app_install" type="button" class="btn btn-default" ng-if="!local.installation" data-toggle="modal" data-target="#app_install_modal">
<span class="glyphicon glyphicon-save"></span> 安装 <span class="glyphicon glyphicon-save"></span> 安装
</button> </button>
<button id="app_add" type="button" class="btn btn-default" ng-if="!app.installation"> <button id="app_add" type="button" class="btn btn-default" ng-if="!local.installation">
<span class="glyphicon glyphicon-plus"></span> 添加 <span class="glyphicon glyphicon-plus"></span> 添加
</button> </button>
<div id="cloud_wrapper" class="cloud input-group pull-right hide" ng-if="app.installation"> <div id="cloud_wrapper" class="cloud input-group pull-right hide" ng-if="local.installation">
<span class="input-group-addon"><span class="glyphicon glyphicon-cloud"></span></span> <span class="input-group-addon"><span class="glyphicon glyphicon-cloud"></span></span>
<input id="cloud_address" type="text" class="form-control" value="255.255.255.255:65535"> <input id="cloud_address" type="text" class="form-control" value="255.255.255.255:65535">
</div> </div>
<button id="cloud_button" type="button" class="cloud btn btn-default pull-right" ng-if="app.installation"> <button id="cloud_button" type="button" class="cloud btn btn-default pull-right" ng-if="local.installation && app.network">
<span class="glyphicon glyphicon-cloud"></span> 反重力场 <span class="glyphicon glyphicon-cloud"></span> 反重力场
</button> </button>
</h1> </h1>
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
<label for="app_install_installation">安装位置</label> <label for="app_install_installation">安装位置</label>
<div class="input-group"> <div class="input-group">
<input id="app_install_installation" type="text" class="form-control" value="{{app.default_installation_path}}"> <input id="app_install_installation" type="text" class="form-control" value="{{default_installation_path}}">
<span class="input-group-btn"> <span class="input-group-btn">
<button class="btn btn-default" type="button">浏览</button> <button class="btn btn-default" type="button">浏览</button>
</span> </span>
...@@ -73,12 +73,12 @@ ...@@ -73,12 +73,12 @@
</div> </div>
<label ng-if="app.has_extra_languages">语言包</label> <!--<label ng-if="app.mods | filter: {type: 'language'}">语言包</label>
<div class="checkbox" ng-repeat="(lang, download) in app.extra_languages"> <div class="checkbox" ng-repeat="(mod) in app.mods | filter: {type: 'language'}">
<label> <label>
<input type="checkbox" checked> {{lang | language_translate}} <input type="checkbox" checked> {{mod.languages[0] | language_translate}}
</label> </label>
</div> </div>-->
</form> </form>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
...@@ -89,12 +89,12 @@ ...@@ -89,12 +89,12 @@
</div> </div>
</div> </div>
<input id="app_add_file" class="hide" type="file" accept="application/octet-stream"/> <input id="app_add_file" class="hide" type="file" accept="application/octet-stream"/>
<div class="progress progress-striped active" ng-repeat="item in installing"> <div class="progress progress-striped active" ng-repeat="item in runtime.installing">
<div class="progress-bar" role="progressbar" aria-valuenow="{{item.progress}}" aria-valuemin="0" aria-valuemax="100" style="width:{{item.progress}}%"> <div class="progress-bar" role="progressbar" aria-valuenow="{{item.progress}}" aria-valuemin="0" aria-valuemax="100" style="width:{{item.progress}}%">
{{item.label}} {{item.label}}
</div> </div>
</div> </div>
{{app.summary}} <div ng-bind-html="app.summary | markdown"></div>
<h2 class="sub-header">好友</h2> <h2 class="sub-header">好友</h2>
<p>您有 8 位好友玩过 {{app.name}},有 2 位正在玩</p> <p>您有 8 位好友玩过 {{app.name}},有 2 位正在玩</p>
...@@ -121,4 +121,28 @@ ...@@ -121,4 +121,28 @@
<div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 60%;"> <div class="progress-bar" role="progressbar" aria-valuenow="60" aria-valuemin="0" aria-valuemax="100" style="width: 60%;">
<span class="sr-only">60% Complete</span> <span class="sr-only">60% Complete</span>
</div> </div>
</div>
<div ng-show="local.installation">
<h2 class="sub-header">设置</h2>
<button id="app_uninstall" type="button" class="btn btn-default" data-toggle="modal" data-target="#app_uninstall_modal" ng-disable="runtime.running || runtime.uninstalling">
<span class="glyphicon glyphicon-trash"></span> 卸载
</button>
<div class="modal fade" id="app_uninstall_modal" tabindex="-1" role="dialog" aria-labelledby="app_uninstall_modal_label" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
<h4 class="modal-title" id="app_uninstall_modal_label">卸载 {{app.name}}</h4>
</div>
<div class="modal-body">
确认卸载?
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
<button type="button" class="btn btn-danger" data-dismiss="modal" ng-click="uninstall()">卸载</button>
</div>
</div>
</div>
</div>
</div> </div>
\ No newline at end of file
[
{
"id": "th135",
"category": "game",
"name": "东方心绮楼",
"network": {
"proto": "udp",
"port": 10800
},
"main": "th135.exe",
"summary": "喵喵喵喵喵帕斯\nnyanpass nyanpass",
"download": {
"url": "http://test2.my-card.in/downloads/maotama/th135_1.33.7z",
"size": 313177031,
"checksum": "ab3c7f4646e080fb88959978865ebf24"
},
"languages": {
"ja-JP": true,
"zh-CN": {
"url": "http://test2.my-card.in/downloads/maotama/th135_lang_zh-CN_1.33.7z",
"size": 74749190,
"checksum": "49111c67d941e30384251a2026ba67ba"
}
}
},
{
"id": "th123",
"category": "game",
"name": "东方非想天则",
"network": {
"proto": "udp",
"port": 10800
},
"summary": "",
"download": {
"url": "http://test2.my-card.in/downloads/maotama/th123_1.10a.7z",
"size": 250272482,
"checksum": "027a358a7ac014f725ebb8659f1caa6f"
},
"main": "th123.exe",
"languages": {
"ja-JP": true
}
}
]
\ No newline at end of file
...@@ -28,6 +28,8 @@ ...@@ -28,6 +28,8 @@
"node-windows": "^0.1.5", "node-windows": "^0.1.5",
"raw-socket": "^1.2.2", "raw-socket": "^1.2.2",
"humanize": "0.0.9", "humanize": "0.0.9",
"mkdirp": "^0.3.5" "mkdirp": "^0.3.5",
"markdown": "^0.5.0",
"rmdir": "^1.0.4"
} }
} }
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