Skip to content

Commit

Permalink
0.2.0
Browse files Browse the repository at this point in the history
  • Loading branch information
zyr17 committed Apr 28, 2019
1 parent d737425 commit 0622f3b
Show file tree
Hide file tree
Showing 14 changed files with 187 additions and 64 deletions.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,6 @@ UserData
.vscode
data
PaipuAnalyzer
result
result
tempCodeRunner*
lib/config.json
18 changes: 9 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# MajsoulPaipuAnalyzer

自制雀魂牌谱分析工具。
自制雀魂牌谱分析工具。支持国服、日服、国际服。日服和国际服仅进行了少量测试。

目前仅支持四人麻将牌谱分析,分析项目参考天鳳の牌譜解析プログラム的项目实现。目前实现了和牌、放铳、立直、其他、终盘大类中的大部分数据,其他有待实现。

Expand Down Expand Up @@ -88,11 +88,11 @@ result中即为结果。

### 牌谱获取及转换

首先运行Electron应用MajsoulPaipuCrawler。程序会显示雀魂窗口和SimpleMahjong窗口。为了能够分析bug,默认两个页面会打开开发者工具。由于技术原因,首次登陆雀魂以后需要刷新界面(杂项-刷新)才能正常解析牌谱
首先运行Electron应用MajsoulPaipuCrawler。程序会显示雀魂窗口和SimpleMahjong窗口。为了能够分析bug,默认两个页面会打开开发者工具。由于技术原因,第三方账户登陆可能出现问题,请使用网页-登陆专用窗口登陆后刷新雀魂窗口。默认为国服,如果要切换到其他服请在网页菜单中选择

在成功登陆后,可以选择牌谱-查看已有牌谱情报。如果没有出现错误那么说明已经可以开始获取牌谱。然后进入牌谱界面,此时再次查看牌谱情报应该会成功获取到约10个牌谱情报。由于雀魂牌谱采用每次加载约10个且滚到牌谱页面底部才触发加载的方式,为了获取全部牌谱需要将滚动条滚到最底部。可以采用鼠标拖动滚动条并在底部抽搐的方式。

在确认所有牌谱已被加载出来后,点击牌谱-下载&转换牌谱来对获取到的牌谱进行下载和格式转换。转换会跳过三麻牌谱。转换进度显示在SimpleMahjong窗口的左上角。需要注意的是,由于技术原因,最近几天打完的牌谱目前并不能成功获取,请过几天再次尝试。
在确认所有牌谱已被加载出来后,点击牌谱-下载&转换牌谱来对获取到的牌谱进行下载和格式转换。转换会跳过三麻和比赛牌谱。转换进度显示在SimpleMahjong窗口的左上角。需要注意的是,由于技术原因,最近几天打完的牌谱目前并不能成功获取,请过几天再次尝试。

每个账户会有自己的独立ID,这个ID和加好友时候的那个ID是不一样的,游戏里大概不能直接看到?如果登陆多个账户,会将每个账户的资料按照ID分别存储,不会混在一起。牌谱下载及转换内容存储于data文件夹,避免重复下载和转换,每次进行下载仅会尝试下载转换未下载的牌谱。存储方式不再赘述,感兴趣的人翻一翻大概就能明白了。

Expand All @@ -106,28 +106,28 @@ result中即为结果。

## 已知问题

繁体中文的系统暂时无法正确显示
分析国际服数据时请确认自己的网络环境可以基本流畅访问Google Facebook等网站,否则很可能无法正常获取牌谱

Ubuntu高版本中可能会出现GUI将可执行文件当做动态链接库的情况。目前没有找到解决方法,请使用Terminal执行。

如果运行Electron时出现游戏界面黑屏、白屏、崩溃等问题,有可能是显卡对WebGL的支持问题,可以尝试将resources/app/main.js文件第21行的双斜杠删去,关闭硬件加速运行。

由于设计时从未参加过比赛场,发现问题后开了个比赛场测试并发现比赛场数据和想象中有较大出入,目前会直接忽略比赛场牌谱数据,在以后做了相关实现后加入。

出现部分牌谱的和牌数据采用新格式,出现原因和时机不明。目前先忽略这些牌谱。

由于本人较菜没有上圣没法打王座,相关牌谱可能会出现bug。

## 联系

如果发现任何bug,可以通过github或是jzjqz17@gmail.com说明。
如果发现任何bug,可以通过[github](https://github.com/zyr17/MajsoulPaipuAnalyzer/issues)或是jzjqz17@gmail.com说明。

## 致谢

该项目使用或曾经使用了这些项目的代码,感谢他们。
该项目使用或曾经使用了这些项目的资源,感谢他们。

[wsHook](https://github.com/skepticfx/wshook)

[CJsonObject](https://github.com/Bwar/CJsonObject)

[wssip](https://github.com/nccgroup/wssip)
[wssip](https://github.com/nccgroup/wssip)

[牌面图像](https://mj-king.net/sozai/)
13 changes: 13 additions & 0 deletions SimpleMahjong/const.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,19 @@ const hanname = [
['国士无双十三面', 'kokushijusan'], ['大四喜', 'daisushi'], ['小四喜', 'shousushi'], ['四杠子', 'sukantsu'],
['宝牌', 'dora'], ['里宝牌', 'ura'], ['红宝牌', 'aka'],
];
var majsoulfanid2name = [
'',
'门前清自摸和','立直','枪杠','岭上开花','海底摸月',
'河底捞鱼','役牌 白','役牌 发','役牌 中','役牌:门风牌',
'役牌:场风牌','断幺九','一杯口','平和','混全带幺九',
'一气通贯','三色同顺','两立直','三色同刻','三杠子',
'对对和','三暗刻','小三元','混老头','七对子',
'纯全带幺九','混一色','二杯口','清一色','一发',
'宝牌','红宝牌','里宝牌','拔北宝牌','天和',
'地和','大三元','四暗刻','字一色','绿一色',
'清老头','国士无双','小四喜','四杠子','九莲宝灯',
'八连庄','纯正九莲宝灯','四暗刻单骑','国士无双十三面','大四喜'
];
function emptymatchdata(){
return {
'title': '',
Expand Down
62 changes: 37 additions & 25 deletions SimpleMahjong/paipu.js
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ class majsoulpaipuanalyze{
var discardtile = String.fromCharCode(arr[start]) + String.fromCharCode(arr[start + 1]);
start += 2;
var reach = 0, moqie = false, naki = false, dora = '';
var nakiwaynum = null, nakihandtile = null;
var nakiwaynum = null, nakihandtile = '';
var unknownnumber = '';
for (; start < arr.length; ){
if (arr[start] == 0x18){
Expand All @@ -187,7 +187,7 @@ class majsoulpaipuanalyze{
var nakiend = start + nakilength;
var nakiwaynum = arr[start + 5];
[nakihandlength, start] = this.getnumber(arr, start + 7);
[nakihandtile, start] = this.getstring(arr, start, nakihandlength);
if (nakihandlength < 1000) [nakihandtile, start] = this.getstring(arr, start, nakihandlength);
start = nakiend;
}
else if (arr[start] == 0x28){
Expand Down Expand Up @@ -415,7 +415,7 @@ class majsoulpaipuanalyze{
tiles: tiles
};
//console.log(this.onepaipu.gamedata.extra.id, whonum, typename[typenum], View.gamerecord.length);
if (typenum < 1 || typenum > 3) this.sendmessage(whonum + ' LiuJu, ' + typename[typenum], result);
this.sendmessage(whonum + ' LiuJu, ' + typename[typenum], result);
return whonum;
}

Expand Down Expand Up @@ -528,29 +528,41 @@ class majsoulpaipuanalyze{
}
else if (arr[start] == 0x62){
//番种
////TODO: 出现牌谱使用编号代替役名。找到役和编号对应列表。
let len6, len, name;
let len6, len, name, han;
[len6, start] = this.getnumber(arr, start + 1);
if (arr[start] == 0x0a){
[len, start] = this.getnumber(arr, start + 1);
[name, start] = this.decodeUTF8(arr, start, len);
let han = arr[start + 1];
if (
name == '四暗刻单骑' ||
name == '国士无双十三面' ||
name == '大四喜' ||
name == '纯正九莲宝灯'
)
han = 2;
if (yakumanyaku)
han *= 13;
agarires.han.push([name, han]);
start += 2;
}
else{
start += len6;
this.rawdata = undefined;
for (let end6 = len6 + start; start < end6; ){
if (arr[start] == 0x0a){
[len, start] = this.getnumber(arr, start + 1);
[name, start] = this.decodeUTF8(arr, start, len);
}
else if (arr[start] == 0x10){
han = arr[start + 1];
if (
name == '四暗刻单骑' ||
name == '国士无双十三面' ||
name == '大四喜' ||
name == '纯正九莲宝灯'
)
han = 2;
if (yakumanyaku)
han *= 13;
start += 2;
}
else if (arr[start] == 0x18){
name = majsoulfanid2name[arr[start + 1]];
start += 2;
}
else{
let cmd;
[cmd, start] = this.getnumber(arr, start);
let addlen = cmd % 8 == 2;
unknownnumber += ' ' + cmd;
[cmd, start] = this.getnumber(arr, start);
if (addlen)
start += cmd;
}
}
agarires.han.push([name, han]);
}
else if (arr[start] == 0x68){
//符
Expand Down Expand Up @@ -880,7 +892,7 @@ class majsoulpaipuanalyze{
}
console.log('paipu #' + this.nowgamedata + ' complete. ' + d.toString());
if (this.rawdata == undefined){
console.log("but it's new type paipu, skip it for now.");
console.log("but it's an unsupported paipu, skip it for now.");
}
}
else{
Expand Down
2 changes: 1 addition & 1 deletion appveyor-linux.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: 0.1.5.{build}
version: 0.2.0.{build}
image: Ubuntu1804
branches:
only:
Expand Down
2 changes: 1 addition & 1 deletion appveyor-win.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version: 0.1.5.{build}
version: 0.2.0.{build}
branches:
only:
- master
Expand Down
17 changes: 9 additions & 8 deletions doc/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@ MajsoulPaipuAnalyzer简易使用说明

操作流程
1. 运行MajsoulPaipuCrawler。会出现两个窗口,雀魂网页窗口和数据分析窗口。
2. 已经自动登陆雀魂则跳过该步。未登陆则登陆雀魂,并在成功进入主界面后选择 杂项-刷新 来刷新页面重新进入。
3. 点击牌谱,选择 牌谱-查看已有牌谱情报, 确认成功获取到了用户ID,以及部分牌谱信息。对于已经获取过的牌谱信息会缓存。
4. 由于雀魂不会一次性将所有牌谱信息发送,请将滚动条往下拖以加载更早的牌谱,直到想要分析的牌谱全部出现在了牌谱列表中。
5. 转到数据分析窗口,选择 牌谱-下载&转换牌谱。会弹窗展示下载牌谱数量,然后窗口左上角会给出进度。全部完成会弹窗提示。
6. 由于技术原因,较新的牌谱(约3天内)无法下载,请以后重试。
7. 关闭两个窗口,编辑config.json设置分析牌谱类型。常用设置在下文给出。
8. 运行PaipuAnalyzer.exe查看结果。
2. 选择服务器,默认进入国服,如果要进入其他服务器请选择网页-对应服务器。
3. 登陆雀魂账号。如果使用第三方账号登陆,且发现无法成功登陆请使用网页-登陆专用窗口进行登陆,然后关闭专用窗口并刷新雀魂网页窗口。
4. 点击牌谱,选择 牌谱-查看已有牌谱情报, 确认成功获取到了用户ID,以及部分牌谱信息。对于已经获取过的牌谱信息会缓存。
5. 由于雀魂不会一次性将所有牌谱信息发送,请将滚动条往下拖以加载更早的牌谱,直到想要分析的牌谱全部出现在了牌谱列表中。
6. 转到数据分析窗口,选择 牌谱-下载&转换牌谱。会弹窗展示下载牌谱数量,然后窗口左上角会给出进度。全部完成会弹窗提示。
7. 由于技术原因,较新的牌谱(约3天内)无法下载,请以后重试。
8. 关闭两个窗口,编辑config.json设置分析牌谱类型。常用设置在下文给出。
9. 运行PaipuAnalyzer.exe查看结果。


config.json常用设置

-1:第二行language默认为简体中文zh-CN,若需要使用简体转的繁体中文请改成zh-TW,瞎翻的英文请改成en-US。注意繁中目前没有经过任何测试不保证可用,若不可用请等待后续版本。。
-1:第二行language默认为简体中文zh-CN,若需要使用简体转的繁体中文请改成zh-TW,瞎翻的英文请改成en-US。

0. 啥都不改默认分析全部牌谱

Expand Down
2 changes: 1 addition & 1 deletion doc/config.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
指牌谱分析使用的语言。目前仅对应中文和基本不能读的英文
指牌谱分析使用的语言。目前仅对应简体中文,机翻繁体中文和基本不能读的英文
"language": "zh-CN",

指牌谱来源。目前来源均为雀魂
Expand Down
6 changes: 6 additions & 0 deletions doc/release-notes.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
0.2.0

1.对于雀魂0.5版本中和牌数据格式变化的对应
2.增加选项支持日服和国际服
3.针对微信登陆的BUG修复;同时为第三方登陆增加登陆专用窗口来避免第三方登陆的问题
4.牌谱转换时途中流局BUG修复
34 changes: 34 additions & 0 deletions lib/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
"use strict";

const fs = require('fs');
const path = require('path');

var config = undefined;

function loadconfig(){
let p = path.join(__dirname, 'config.json');
if (fs.existsSync(p))
config = JSON.parse(fs.readFileSync(p).toString());
else{
config = {
DefaultURL: 'https://majsoul.union-game.com/0/'
};
fs.writeFileSync(p, JSON.stringify(config));
}
}

var configF = {
get: function (id){
if (config == undefined)
loadconfig();
return config[id];
},
set: function (id, val){
config[id] = val;
fs.writeFileSync(path.join(__dirname, 'config.json'), JSON.stringify(config));
}
}

module.exports = {
config: configF
};
7 changes: 5 additions & 2 deletions lib/majsoul/analyze.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use strict";

var clientrequest = {};
var UserID = 0;
var UserID = -1;
var paipugamedata = {};

function decodeUTF8(data, start = undefined, length = undefined){
Expand Down Expand Up @@ -420,7 +420,7 @@ function analyzepaipu(arr, start){
}
//var pp = path.join(__dirname, '../../data/gamedata.txt');
//if (valid && data.extra.id != undefined) fs.appendFileSync(pp, JSON.stringify(data) + '\n');
if (data.extra.id != undefined) paipugamedata[data.extra.id] = data;
if (data.extra.id != undefined && data.accountid >= 0) paipugamedata[data.extra.id] = data;
ss += paipulength;
}
}
Expand Down Expand Up @@ -448,6 +448,9 @@ function analyze(sender, data){
if (req == '.lq.Lobby.oauth2Login'){
analyzelogin(sender, arr8, 5);
}
else if (req == '.lq.Lobby.login'){
analyzelogin(sender, arr8, 5);
}
else if (req == '.lq.Lobby.fetchGameRecordList'){
analyzepaipu(arr8, 5);
}
Expand Down
7 changes: 4 additions & 3 deletions lib/majsoul/browseinject.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
console.log("try add jquery trigger");
const electron = require("electron");
const ipcr = electron.ipcRenderer;
var electron = require("electron");
var ipcr = electron.ipcRenderer;
function addjquery() {
//console.log("check jquery");
var flag = 1;
Expand All @@ -26,4 +26,5 @@ function addjquery() {
}
}
addjqueryintervalid = setInterval(addjquery, 1000);
addjqueryintervalremain = 30;
addjqueryintervalremain = 30;
addjquery();
Loading

0 comments on commit 0622f3b

Please sign in to comment.