设为首页收藏本站

ZMX - IT技术交流论坛 - 无限Perfect,追求梦想 - itzmx.com

 找回密码
 注册论坛

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

用百度帐号登录

只需两步,快速登录

搜索

有人知道游戏Nyakori's rabbit doll用的是什么加密吗?

查看数: 3099 | 评论数: 21 | 收藏 0
关灯 | 提示:支持键盘翻页<-左 右->
    组图打开中,请稍候......
发布时间: 2022/7/9 13:00

正文摘要:

本帖最后由 EATB 于 2022/7/9 15:55 编辑 有人知道游戏Nyakori's rabbit doll用的是什么加密吗?或者怎么解密这个游戏的图片文件吗?或者找到是用什么方法加密的也行(具体的) steam的一个游戏,这个游戏的引擎 ...

回复

Hileb|Google Chrome 73.0.3683.121|Windows 7 发表于 2022/8/28 13:20
天涯海角搜一下: 百度 谷歌 360 搜狗 有道 雅虎 必应 即刻
这就是大佬么
EATB|Google Chrome 104.0.0.0|Windows 10 发表于 2022/8/21 18:10
现在最大的问题是如何查看和编辑mrd.min.bin文件
EATB|Google Chrome 104.0.0.0|Windows 10 发表于 2022/8/21 18:06
Nyakori's rabbit doll的mrd.min.bin文件内已经包含了所有需要的js


这句话可能不太对,因为js文件夹内除了mrd.min.bin的文件大小为13.5MB,但是mrd.min.bin文件只有6.1MB
EATB|Google Chrome 104.0.0.0|Windows 10 发表于 2022/8/21 17:48
把js文件夹内除了mrd.min.bin以外的文件都删除后,游戏仍然能正常运行及游玩
EATB|Google Chrome 104.0.0.0|Windows 10 发表于 2022/8/21 17:37
如果index.html文件被修改,打开game.exe就自动退出,并不是闪退,因为游戏退出的动画就是进程被关闭的样子

这说明index.html文件有保护,无法修改
EATB|Google Chrome 104.0.0.0|Windows 10 发表于 2022/8/21 17:32

通过对比,这个游戏的index.html文件的head部分多出了这部分代码

  1. <meta itemprop="name" content="喵可莉的兔玩偶"/>
  2.                 <meta itemprop="image" content="icon/share.png" />
  3.                 <meta name="description" itemprop="description" content="RPGMaker MV. WebGL Mode." />
  4.                 <meta name="keywords" content="喵可莉,喵可莉的兔玩偶" />
复制代码


body部分被替换为

  1. <script type="text/javascript">
  2.                 window.is_nwjc = true;
  3.                 var xhr = new XMLHttpRequest();
  4.                 xhr.responseType = 'arraybuffer';
  5.                 xhr.open('GET', 'js/mrd.min.bin');
  6.                 xhr.onload = function() {
  7.                         if(xhr.status < 400)
  8.                         {
  9.                                 nw.Window.get().evalNWBin(null, xhr.response);
  10.                         }
  11.                         window._setIntervalt = setInterval(function() {
  12.                                 if(window.onIndexCheckOK)
  13.                                 {
  14.                                         clearInterval(window._setIntervalt);
  15.                                         SceneManager.run(Scene_Boot);
  16.                                 }
  17.                         }, 100);
  18.                 };
  19.                 xhr.send();
  20.                 </script>
复制代码


body部分被完全用于加载插件(mrd.min.bin),没有看到用于加载其他插件的代码,所以其他的插件及有可能是被插件(mrd.min.bin)加载的
head部分不太清楚是感什么的,但是肯定和WebGL有关

如果把插件(mrd.min.bin)删除,或者把body被替换的部分删除,打开game.exe就会一片黑
打开game.exe就会一片黑的原因就是什么都没有加载
EATB|Google Chrome 104.0.0.0|Windows 10 发表于 2022/8/21 17:23

这个是普通RPG游戏的的index.html文件的内容

  1. <!DOCTYPE html>
  2. <html>
  3.     <head>
  4.         <meta charset="UTF-8">
  5.         <meta name="apple-mobile-web-app-capable" content="yes">
  6.         <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
  7.         <meta name="viewport" content="user-scalable=no">
  8.         <link rel="icon" href="icon/icon.png" type="image/png">
  9.         <link rel="apple-touch-icon" href="icon/icon.png">
  10.         <link rel="stylesheet" type="text/css" href="fonts/gamefont.css">
  11.         <title>XXXX ver1.00</title>
  12.     </head>
  13.     <body style="background-color: black">
  14.         <script type="text/javascript" src="js/libs/pixi.js"></script>
  15.         <script type="text/javascript" src="js/libs/pixi-tilemap.js"></script>
  16.         <script type="text/javascript" src="js/libs/pixi-picture.js"></script>
  17.         <script type="text/javascript" src="js/libs/fpsmeter.js"></script>
  18.         <script type="text/javascript" src="js/libs/lz-string.js"></script>
  19.         <script type="text/javascript" src="js/libs/iphone-inline-video.browser.js"></script>
  20.         <script type="text/javascript" src="js/rpg_core.js"></script>
  21.         <script type="text/javascript" src="js/rpg_managers.js"></script>
  22.         <script type="text/javascript" src="js/rpg_objects.js"></script>
  23.         <script type="text/javascript" src="js/rpg_scenes.js"></script>
  24.         <script type="text/javascript" src="js/rpg_sprites.js"></script>
  25.         <script type="text/javascript" src="js/rpg_windows.js"></script>
  26.         <script type="text/javascript" src="js/plugins.js"></script>
  27.         <script type="text/javascript" src="js/main.js"></script>
  28.     </body>
  29. </html>
复制代码
EATB|Google Chrome 104.0.0.0|Windows 10 发表于 2022/8/21 17:22
这是这个游戏的index.html,里面只加载了一个插件(mrd.min.bin),这说明此游戏的资源文件价值极有可能是靠插件(mrd.min.bin)加载的,这个插件的大小为6.1MB

  1. <!DOCTYPE html>
  2. <html>
  3.     <head>
  4.         <meta charset="UTF-8">
  5.         <meta name="apple-mobile-web-app-capable" content="yes">
  6.         <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
  7.         <meta name="viewport" content="user-scalable=no">
  8.                 <meta itemprop="name" content="喵可莉的兔玩偶"/>
  9.                 <meta itemprop="image" content="icon/share.png" />
  10.                 <meta name="description" itemprop="description" content="RPGMaker MV. WebGL Mode." />
  11.                 <meta name="keywords" content="喵可莉,喵可莉的兔玩偶" />
  12.         <link rel="icon" href="icon/icon.png" type="image/png">
  13.         <link rel="apple-touch-icon" href="icon/icon.png">
  14.         <link rel="stylesheet" type="text/css" href="fonts/gamefont.css">
  15.         <title></title>
  16.     </head>
  17.     <body style="background-color: black">
  18.                 <script type="text/javascript">
  19.                 window.is_nwjc = true;
  20.                 var xhr = new XMLHttpRequest();
  21.                 xhr.responseType = 'arraybuffer';
  22.                 xhr.open('GET', 'js/mrd.min.bin');
  23.                 xhr.onload = function() {
  24.                         if(xhr.status < 400)
  25.                         {
  26.                                 nw.Window.get().evalNWBin(null, xhr.response);
  27.                         }
  28.                         window._setIntervalt = setInterval(function() {
  29.                                 if(window.onIndexCheckOK)
  30.                                 {
  31.                                         clearInterval(window._setIntervalt);
  32.                                         SceneManager.run(Scene_Boot);
  33.                                 }
  34.                         }, 100);
  35.                 };
  36.                 xhr.send();
  37.                 </script>
  38.     </body>
  39. </html>
复制代码
Hileb|Google Chrome 73.0.3683.121|Windows 7 发表于 2022/7/17 00:08
看起来还不错,感谢游戏推荐
EATB|Google Chrome 103.0.0.0|Windows 10 发表于 2022/7/12 11:06
ICP13013206-7 发表于 2022/7/11 05:32
帮顶,感谢游戏推荐。

你是不是搞错了什么?
ICP13013206-7|Firefox 100.0|Windows 10 发表于 2022/7/11 05:32
帮顶,感谢游戏推荐。
EATB 发表于 2022/7/9 21:01
https://rpg.blue/thread-477772-1-1.html

找到了一点线索,
部分资源是【预载入到本地硬盘】的,部分资源是【预载入内存】的。

立绘,se,me,bgm这种不会卡MV场景加载的都会预载到硬盘

也就是说cg文件可能会被解密到硬盘中,但是目前发现此游戏创建的文件只有c盘的“C:\Users\用户名\AppData\Local\Nyakori's Rabbit Doll”


图:webgl告诉我你的显卡可以用S3TC的压缩格式。

如果MV要使用这些压缩纹理来节省图片内存占用的话,有什么方法可以让MV使用压缩纹理么。

这句说明cg文件不一定是普通的图片格式,也可能会以其他形式显示成图片


因为MV的资源管理模式几乎就是用到再加载,其实就是边玩边加载图片,这样图片稍微加载慢一点就出LOADING了,玩玩就LOADING,很烦。但为什么其他网游没这个问题,因为他们在游戏启动的时候一次性把资源全都预加载上来了。

这句已经印证游戏的资源文件会被提前加载好,这也就是为什么一开始游戏会有加载图,而且Game.exe对CPU和GPU的利用率提高
EATB|Google Chrome 103.0.0.0|Windows 10 发表于 2022/7/9 13:28
这个游戏的CG大概是用MD5来加密的,在plugins文件夹找到了个叫md5.js的文件
听说md5加密是无解的,如果是无解的游戏又是怎么显示被md5加密的cg文件呢?

  1. var md5 = md5 || {};
  2.         (function($){
  3.                 var rotateLeft = function(lValue, iShiftBits) {
  4.                         return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
  5.                 }
  6.                 var addUnsigned = function(lX, lY) {
  7.                         var lX4, lY4, lX8, lY8, lResult;
  8.                         lX8 = (lX & 0x80000000);
  9.                         lY8 = (lY & 0x80000000);
  10.                         lX4 = (lX & 0x40000000);
  11.                         lY4 = (lY & 0x40000000);
  12.                         lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
  13.                         if (lX4 & lY4) return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
  14.                         if (lX4 | lY4) {
  15.                                 if (lResult & 0x40000000) return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
  16.                                 else return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
  17.                         } else {
  18.                                 return (lResult ^ lX8 ^ lY8);
  19.                         }
  20.                 }
  21.                 var F = function(x, y, z) {
  22.                         return (x & y) | ((~ x) & z);
  23.                 }
  24.                 var G = function(x, y, z) {
  25.                         return (x & z) | (y & (~ z));
  26.                 }
  27.                 var H = function(x, y, z) {
  28.                         return (x ^ y ^ z);
  29.                 }
  30.                 var I = function(x, y, z) {
  31.                         return (y ^ (x | (~ z)));
  32.                 }
  33.                 var FF = function(a, b, c, d, x, s, ac) {
  34.                         a = addUnsigned(a, addUnsigned(addUnsigned(F(b, c, d), x), ac));
  35.                         return addUnsigned(rotateLeft(a, s), b);
  36.                 };
  37.                 var GG = function(a, b, c, d, x, s, ac) {
  38.                         a = addUnsigned(a, addUnsigned(addUnsigned(G(b, c, d), x), ac));
  39.                         return addUnsigned(rotateLeft(a, s), b);
  40.                 };
  41.                 var HH = function(a, b, c, d, x, s, ac) {
  42.                         a = addUnsigned(a, addUnsigned(addUnsigned(H(b, c, d), x), ac));
  43.                         return addUnsigned(rotateLeft(a, s), b);
  44.                 };
  45.                 var II = function(a, b, c, d, x, s, ac) {
  46.                         a = addUnsigned(a, addUnsigned(addUnsigned(I(b, c, d), x), ac));
  47.                         return addUnsigned(rotateLeft(a, s), b);
  48.                 };
  49.                 var convertToWordArray = function(string) {
  50.                         var lWordCount;
  51.                         var lMessageLength = string.length;
  52.                         var lNumberOfWordsTempOne = lMessageLength + 8;
  53.                         var lNumberOfWordsTempTwo = (lNumberOfWordsTempOne - (lNumberOfWordsTempOne % 64)) / 64;
  54.                         var lNumberOfWords = (lNumberOfWordsTempTwo + 1) * 16;
  55.                         var lWordArray = Array(lNumberOfWords - 1);
  56.                         var lBytePosition = 0;
  57.                         var lByteCount = 0;
  58.                         while (lByteCount < lMessageLength) {
  59.                                 lWordCount = (lByteCount - (lByteCount % 4)) / 4;
  60.                                 lBytePosition = (lByteCount % 4) * 8;
  61.                                 lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount) << lBytePosition));
  62.                                 lByteCount++;
  63.                         }
  64.                         lWordCount = (lByteCount - (lByteCount % 4)) / 4;
  65.                         lBytePosition = (lByteCount % 4) * 8;
  66.                         lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
  67.                         lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
  68.                         lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
  69.                         return lWordArray;
  70.                 };
  71.                 var wordToHex = function(lValue) {
  72.                         var WordToHexValue = "", WordToHexValueTemp = "", lByte, lCount;
  73.                         for (lCount = 0; lCount <= 3; lCount++) {
  74.                                 lByte = (lValue >>> (lCount * 8)) & 255;
  75.                                 WordToHexValueTemp = "0" + lByte.toString(16);
  76.                                 WordToHexValue = WordToHexValue + WordToHexValueTemp.substr(WordToHexValueTemp.length - 2, 2);
  77.                         }
  78.                         return WordToHexValue;
  79.                 };
  80.                 var uTF8Encode = function(string) {
  81.                         string = string.replace(/\x0d\x0a/g, "\x0a");
  82.                         var output = "";
  83.                         for (var n = 0; n < string.length; n++) {
  84.                                 var c = string.charCodeAt(n);
  85.                                 if (c < 128) {
  86.                                         output += String.fromCharCode(c);
  87.                                 } else if ((c > 127) && (c < 2048)) {
  88.                                         output += String.fromCharCode((c >> 6) | 192);
  89.                                         output += String.fromCharCode((c & 63) | 128);
  90.                                 } else {
  91.                                         output += String.fromCharCode((c >> 12) | 224);
  92.                                         output += String.fromCharCode(((c >> 6) & 63) | 128);
  93.                                         output += String.fromCharCode((c & 63) | 128);
  94.                                 }
  95.                         }
  96.                         return output;
  97.                 };
  98.                 $.compute = function(string) {
  99.                                 var x = Array();
  100.                                 var k, AA, BB, CC, DD, a, b, c, d;
  101.                                 var S11=7, S12=12, S13=17, S14=22;
  102.                                 var S21=5, S22=9 , S23=14, S24=20;
  103.                                 var S31=4, S32=11, S33=16, S34=23;
  104.                                 var S41=6, S42=10, S43=15, S44=21;
  105.                                 string = uTF8Encode(string);
  106.                                 x = convertToWordArray(string);
  107.                                 a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;
  108.                                 for (k = 0; k < x.length; k += 16) {
  109.                                         AA = a; BB = b; CC = c; DD = d;
  110.                                         a = FF(a, b, c, d, x[k+0],  S11, 0xD76AA478);
  111.                                         d = FF(d, a, b, c, x[k+1],  S12, 0xE8C7B756);
  112.                                         c = FF(c, d, a, b, x[k+2],  S13, 0x242070DB);
  113.                                         b = FF(b, c, d, a, x[k+3],  S14, 0xC1BDCEEE);
  114.                                         a = FF(a, b, c, d, x[k+4],  S11, 0xF57C0FAF);
  115.                                         d = FF(d, a, b, c, x[k+5],  S12, 0x4787C62A);
  116.                                         c = FF(c, d, a, b, x[k+6],  S13, 0xA8304613);
  117.                                         b = FF(b, c, d, a, x[k+7],  S14, 0xFD469501);
  118.                                         a = FF(a, b, c, d, x[k+8],  S11, 0x698098D8);
  119.                                         d = FF(d, a, b, c, x[k+9],  S12, 0x8B44F7AF);
  120.                                         c = FF(c, d, a, b, x[k+10], S13, 0xFFFF5BB1);
  121.                                         b = FF(b, c, d, a, x[k+11], S14, 0x895CD7BE);
  122.                                         a = FF(a, b, c, d, x[k+12], S11, 0x6B901122);
  123.                                         d = FF(d, a, b, c, x[k+13], S12, 0xFD987193);
  124.                                         c = FF(c, d, a, b, x[k+14], S13, 0xA679438E);
  125.                                         b = FF(b, c, d, a, x[k+15], S14, 0x49B40821);
  126.                                         a = GG(a, b, c, d, x[k+1],  S21, 0xF61E2562);
  127.                                         d = GG(d, a, b, c, x[k+6],  S22, 0xC040B340);
  128.                                         c = GG(c, d, a, b, x[k+11], S23, 0x265E5A51);
  129.                                         b = GG(b, c, d, a, x[k+0],  S24, 0xE9B6C7AA);
  130.                                         a = GG(a, b, c, d, x[k+5],  S21, 0xD62F105D);
  131.                                         d = GG(d, a, b, c, x[k+10], S22, 0x2441453);
  132.                                         c = GG(c, d, a, b, x[k+15], S23, 0xD8A1E681);
  133.                                         b = GG(b, c, d, a, x[k+4],  S24, 0xE7D3FBC8);
  134.                                         a = GG(a, b, c, d, x[k+9],  S21, 0x21E1CDE6);
  135.                                         d = GG(d, a, b, c, x[k+14], S22, 0xC33707D6);
  136.                                         c = GG(c, d, a, b, x[k+3],  S23, 0xF4D50D87);
  137.                                         b = GG(b, c, d, a, x[k+8],  S24, 0x455A14ED);
  138.                                         a = GG(a, b, c, d, x[k+13], S21, 0xA9E3E905);
  139.                                         d = GG(d, a, b, c, x[k+2],  S22, 0xFCEFA3F8);
  140.                                         c = GG(c, d, a, b, x[k+7],  S23, 0x676F02D9);
  141.                                         b = GG(b, c, d, a, x[k+12], S24, 0x8D2A4C8A);
  142.                                         a = HH(a, b, c, d, x[k+5],  S31, 0xFFFA3942);
  143.                                         d = HH(d, a, b, c, x[k+8],  S32, 0x8771F681);
  144.                                         c = HH(c, d, a, b, x[k+11], S33, 0x6D9D6122);
  145.                                         b = HH(b, c, d, a, x[k+14], S34, 0xFDE5380C);
  146.                                         a = HH(a, b, c, d, x[k+1],  S31, 0xA4BEEA44);
  147.                                         d = HH(d, a, b, c, x[k+4],  S32, 0x4BDECFA9);
  148.                                         c = HH(c, d, a, b, x[k+7],  S33, 0xF6BB4B60);
  149.                                         b = HH(b, c, d, a, x[k+10], S34, 0xBEBFBC70);
  150.                                         a = HH(a, b, c, d, x[k+13], S31, 0x289B7EC6);
  151.                                         d = HH(d, a, b, c, x[k+0],  S32, 0xEAA127FA);
  152.                                         c = HH(c, d, a, b, x[k+3],  S33, 0xD4EF3085);
  153.                                         b = HH(b, c, d, a, x[k+6],  S34, 0x4881D05);
  154.                                         a = HH(a, b, c, d, x[k+9],  S31, 0xD9D4D039);
  155.                                         d = HH(d, a, b, c, x[k+12], S32, 0xE6DB99E5);
  156.                                         c = HH(c, d, a, b, x[k+15], S33, 0x1FA27CF8);
  157.                                         b = HH(b, c, d, a, x[k+2],  S34, 0xC4AC5665);
  158.                                         a = II(a, b, c, d, x[k+0],  S41, 0xF4292244);
  159.                                         d = II(d, a, b, c, x[k+7],  S42, 0x432AFF97);
  160.                                         c = II(c, d, a, b, x[k+14], S43, 0xAB9423A7);
  161.                                         b = II(b, c, d, a, x[k+5],  S44, 0xFC93A039);
  162.                                         a = II(a, b, c, d, x[k+12], S41, 0x655B59C3);
  163.                                         d = II(d, a, b, c, x[k+3],  S42, 0x8F0CCC92);
  164.                                         c = II(c, d, a, b, x[k+10], S43, 0xFFEFF47D);
  165.                                         b = II(b, c, d, a, x[k+1],  S44, 0x85845DD1);
  166.                                         a = II(a, b, c, d, x[k+8],  S41, 0x6FA87E4F);
  167.                                         d = II(d, a, b, c, x[k+15], S42, 0xFE2CE6E0);
  168.                                         c = II(c, d, a, b, x[k+6],  S43, 0xA3014314);
  169.                                         b = II(b, c, d, a, x[k+13], S44, 0x4E0811A1);
  170.                                         a = II(a, b, c, d, x[k+4],  S41, 0xF7537E82);
  171.                                         d = II(d, a, b, c, x[k+11], S42, 0xBD3AF235);
  172.                                         c = II(c, d, a, b, x[k+2],  S43, 0x2AD7D2BB);
  173.                                         b = II(b, c, d, a, x[k+9],  S44, 0xEB86D391);
  174.                                         a = addUnsigned(a, AA);
  175.                                         b = addUnsigned(b, BB);
  176.                                         c = addUnsigned(c, CC);
  177.                                         d = addUnsigned(d, DD);
  178.                                 }
  179.                                 var tempValue = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d);
  180.                                 return tempValue.toLowerCase();
  181.                         }
  182.         })(md5);
复制代码


这是图片文件
EATB|Google Chrome 103.0.0.0|Windows 10 发表于 2022/7/9 13:02
这个游戏的目录结构和文件和普通的RPG游戏都不太一样,比较明显的是greenworks,https://github.com/greenheartgames/greenworks
  1. // Copyright (c) 2015 Greenheart Games Pty. Ltd. All rights reserved.

  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.

  4. // The source code can be found in https://github.com/greenheartgames/greenworks
  5. var fs = require('fs');

  6. var greenworks;

  7. if (process.platform == 'darwin') {
  8.   if (process.arch == 'x64')
  9.     greenworks = require('./lib/greenworks-osx64');
  10.   else if (process.arch == 'ia32')
  11.     greenworks = require('./lib/greenworks-osx32');
  12. } else if (process.platform == 'win32') {
  13.   if (process.arch == 'x64')
  14.     greenworks = require('./lib/greenworks-win64');
  15.   else if (process.arch == 'ia32')
  16.     greenworks = require('./lib/greenworks-win32');
  17. } else if (process.platform == 'linux') {
  18.   if (process.arch == 'x64')
  19.     greenworks = require('./lib/greenworks-linux64');
  20.   else if (process.arch == 'ia32')
  21.     greenworks = require('./lib/greenworks-linux32');
  22. }

  23. function error_process(err, error_callback) {
  24.   if (err && error_callback)
  25.     error_callback(err);
  26. }

  27. greenworks.ugcGetItems = function(options, ugc_matching_type, ugc_query_type,
  28.     success_callback, error_callback) {
  29.   if (typeof options !== 'object') {
  30.     error_callback = success_callback;
  31.     success_callback = ugc_query_type;
  32.     ugc_query_type = ugc_matching_type;
  33.     ugc_matching_type = options;
  34.     options = {
  35.       'app_id': greenworks.getAppId(),
  36.       'page_num': 1
  37.     }
  38.   }
  39.   greenworks._ugcGetItems(options, ugc_matching_type, ugc_query_type,
  40.       success_callback, error_callback);
  41. }

  42. greenworks.ugcGetUserItems = function(options, ugc_matching_type,
  43.     ugc_list_sort_order, ugc_list, success_callback, error_callback) {
  44.   if (typeof options !== 'object') {
  45.     error_callback = success_callback;
  46.     success_callback = ugc_list;
  47.     ugc_list = ugc_list_sort_order;
  48.     ugc_list_sort_order = ugc_matching_type;
  49.     ugc_matching_type = options;
  50.     options = {
  51.       'app_id': greenworks.getAppId(),
  52.       'page_num': 1
  53.     }
  54.   }
  55.   greenworks._ugcGetUserItems(options, ugc_matching_type, ugc_list_sort_order,
  56.       ugc_list, success_callback, error_callback);
  57. }

  58. greenworks.ugcSynchronizeItems = function (options, sync_dir, success_callback,
  59.     error_callback) {
  60.   if (typeof options !== 'object') {
  61.     error_callback = success_callback;
  62.     success_callback = sync_dir;
  63.     sync_dir = options;
  64.     options = {
  65.       'app_id': greenworks.getAppId(),
  66.       'page_num': 1
  67.     }
  68.   }
  69.   greenworks._ugcSynchronizeItems(options, sync_dir, success_callback,
  70.       error_callback);
  71. }

  72. greenworks.publishWorkshopFile = function(options, file_path, image_path, title,
  73.     description, success_callback, error_callback) {
  74.   if (typeof options !== 'object') {
  75.     error_callback = success_callback;
  76.     success_callback = description;
  77.     description = title;
  78.     title = image_path;
  79.     image_path = file_path;
  80.     file_path = options;
  81.     options = {
  82.       'app_id': greenworks.getAppId(),
  83.       'tags': []
  84.     }
  85.   }
  86.   greenworks._publishWorkshopFile(options, file_path, image_path, title,
  87.       description, success_callback, error_callback);
  88. }

  89. greenworks.updatePublishedWorkshopFile = function(options,
  90.     published_file_handle, file_path, image_path, title, description,
  91.     success_callback, error_callback) {
  92.   if (typeof options !== 'object') {
  93.     error_callback = success_callback;
  94.     success_callback = description;
  95.     description = title;
  96.     title = image_path;
  97.     image_path = file_path;
  98.     file_path = published_file_handle;
  99.     published_file_handle = options;
  100.     options = {
  101.       'tags': [] // No tags are set
  102.     }
  103.   }
  104.   greenworks._updatePublishedWorkshopFile(options, published_file_handle,
  105.      file_path, image_path, title, description, success_callback,
  106.      error_callback);
  107. }

  108. // An utility function for publish related APIs.
  109. // It processes remains steps after saving files to Steam Cloud.
  110. function file_share_process(file_name, image_name, next_process_func,
  111.     error_callback, progress_callback) {
  112.   if (progress_callback)
  113.     progress_callback("Completed on saving files on Steam Cloud.");
  114.   greenworks.fileShare(file_name, function() {
  115.     greenworks.fileShare(image_name, function() {
  116.       next_process_func();
  117.     }, function(err) { error_process(err, error_callback); });
  118.   }, function(err) { error_process(err, error_callback); });
  119. }

  120. // Publishing user generated content(ugc) to Steam contains following steps:
  121. // 1. Save file and image to Steam Cloud.
  122. // 2. Share the file and image.
  123. // 3. publish the file to workshop.
  124. greenworks.ugcPublish = function(file_name, title, description, image_name,
  125.     success_callback, error_callback, progress_callback) {
  126.   var publish_file_process = function() {
  127.     if (progress_callback)
  128.       progress_callback("Completed on sharing files.");
  129.     greenworks.publishWorkshopFile(file_name, image_name, title, description,
  130.         function(publish_file_id) { success_callback(publish_file_id); },
  131.         function(err) { error_process(err, error_callback); });
  132.   };
  133.   greenworks.saveFilesToCloud([file_name, image_name], function() {
  134.     file_share_process(file_name, image_name, publish_file_process,
  135.         error_callback, progress_callback);
  136.   }, function(err) { error_process(err, error_callback); });
  137. }

  138. // Update publish ugc steps:
  139. // 1. Save new file and image to Steam Cloud.
  140. // 2. Share file and images.
  141. // 3. Update published file.
  142. greenworks.ugcPublishUpdate = function(published_file_id, file_name, title,
  143.     description, image_name, success_callback, error_callback,
  144.     progress_callback) {
  145.   var update_published_file_process = function() {
  146.     if (progress_callback)
  147.       progress_callback("Completed on sharing files.");
  148.     greenworks.updatePublishedWorkshopFile(published_file_id,
  149.         file_name, image_name, title, description,
  150.         function() { success_callback(); },
  151.         function(err) { error_process(err, error_callback); });
  152.   };

  153.   greenworks.saveFilesToCloud([file_name, image_name], function() {
  154.     file_share_process(file_name, image_name, update_published_file_process,
  155.         error_callback, progress_callback);
  156.   }, function(err) { error_process(err, error_callback); });
  157. }

  158. // Greenworks Utils APIs implmentation.
  159. greenworks.Utils.move = function(source_dir, target_dir, success_callback,
  160.     error_callback) {
  161.   fs.rename(source_dir, target_dir, function(err) {
  162.     if (err) {
  163.       if (error_callback) error_callback(err);
  164.       return;
  165.     }
  166.     if (success_callback)
  167.       success_callback();
  168.   });
  169. }

  170. greenworks.init = function() {
  171.   if (this.initAPI()) return true;
  172.   if (!this.isSteamRunning())
  173.     throw new Error("Steam initialization failed. Steam is not running.");
  174.   var appId;
  175.   try {
  176.     appId = fs.readFileSync('steam_appid.txt', 'utf8');
  177.   } catch (e) {
  178.     throw new Error("Steam initialization failed. Steam is running," +
  179.                     "but steam_appid.txt is missing. Expected to find it in: " +
  180.                     require('path').resolve('steam_appid.txt'));
  181.   }
  182.   if (!/^\d+ *\r?\n?$/.test(appId)) {
  183.     throw new Error("Steam initialization failed. " +
  184.                     "steam_appid.txt appears to be invalid; " +
  185.                     "it should contain a numeric ID: " + appId);
  186.   }
  187.   throw new Error("Steam initialization failed, but Steam is running, " +
  188.                   "and steam_appid.txt is present and valid." +
  189.                   "Maybe that's not really YOUR app ID? " + appId.trim());
  190. }

  191. var EventEmitter = require('events').EventEmitter;
  192. greenworks.__proto__ = EventEmitter.prototype;
  193. EventEmitter.call(greenworks);

  194. greenworks._steam_events.on = function () {
  195.   greenworks.emit.apply(greenworks, arguments);
  196. };

  197. process.versions['greenworks'] = greenworks._version;

  198. module.exports = greenworks;
复制代码

手机版|Archiver|Mail me|网站地图|IT技术交流论坛 ( 闽ICP备13013206号-7 )

GMT+8, 2025/7/17 23:09 , Processed in 0.157090 second(s), 26 queries , MemCache On.

Powered by itzmx! X3.4

© 2011- sakura

快速回复 返回顶部 返回列表