查看: 4256|回复: 8

[搬运汉化] 自動翻訳插件

[复制链接]
梦石
0
星屑
22879
在线时间
8598 小时
注册时间
2011-12-31
回帖
3270
发表于 2017-4-19 11:26:59 | 显示全部楼层 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有账号?注册会员

×
http://triacontane.blogspot.hk/2017/04/blog-post_16.html
 
1.   「文章表示」的文字
2.   「選択肢表示」的選択肢
3.   「地圖名」
4.   各種資料庫値(包括用語)
Image001.png
Image002.png
翻訳API

 翻訳使用了「Microsoft Azure」的「Translator Text API」(Web API)。
https://azure.microsoft.com/ja-jp/services/cognitive-services/

 言語碼指定、翻訳言語自由変更。言語碼参照以下頁面。
https://msdn.microsoft.com/en-us/library/hh456380.aspx

日:ja
簡:zh-CHS
繁zh-CHT

誤訳修正

 翻訳結果保存到「Translations_(翻訳言語碼).json」文件中、ファイルに保存されている内容を返します。JSONファイルは、翻訳前の文章をキー、翻訳後の文章を値とする簡単な構成のため以下のようなJSONエディタ等で簡単に編集できます。(編集は自己責任です)
http://jsoneditoronline.org/

注意


  1.  無料版的「Translator Text API」、1個月只有200万文字翻訳量。 這是插件使用者全員的合計總和。。 (多分不會超過)、 万一超過的場合就不能翻訳了。

  2.  如果句子包括控制字符,並跳過翻譯,因為內容會丟失。

 3.若不能滿足對系統的請求不能。(如需能連線到https://azure.microsoft.com/ja-jp/services/cognitive-services/………)

  4.  「Translator Text API」服務終了的場合、当然這插件就没用了。(代替案は検討します)

评分

参与人数 1星屑 +20 收起 理由
白嫩白嫩的 + 20 塞糖

查看全部评分

漾夕☽星化残月☾

梦石
0
星屑
8611
在线时间
3858 小时
注册时间
2015-5-12
回帖
2022

剧作品鉴家

发表于 2017-4-19 16:54:26 | 显示全部楼层
这不繁不简不日的标题闹哪样……
回复

使用道具 举报

梦石
0
星屑
5343
在线时间
683 小时
注册时间
2016-2-11
回帖
120
发表于 2017-4-19 20:06:31 | 显示全部楼层
冒昧问下楼主国籍{:2_248:}
回复

使用道具 举报

老黄鸡

梦石
4
星屑
45705
在线时间
7948 小时
注册时间
2009-7-6
回帖
13338

MZ评测员RM创作大赛01组委会开拓者贵宾

发表于 2017-4-19 20:30:15 | 显示全部楼层
毕竟机翻
回复

使用道具 举报

梦石
0
星屑
792
在线时间
2 小时
注册时间
2017-4-18
回帖
2
发表于 2017-4-20 00:02:07 | 显示全部楼层
连接打不开。!
回复

使用道具 举报

梦石
0
星屑
22879
在线时间
8598 小时
注册时间
2011-12-31
回帖
3270
 楼主| 发表于 2017-4-20 08:52:56 | 显示全部楼层
MIT
    TranslationManager._accessTokenUrl   = 'https://api.cognitive.microsoft.com/sts/v1.0/issueToken';
    TranslationManager._translateUrl     = 'https://api.microsofttranslator.com/V2/Http.svc/Translate';
    TranslationManager._subscriptionKey1 = 'f78dab007fdb4ad4ad5baaaa01b74829';(帳戸碼)
自動翻訳插件[pre lang="javascript"]//=============================================================================
// AutoTranslation.js
// ----------------------------------------------------------------------------
// Copyright (c) 2015-2017 Triacontane
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php
// ----------------------------------------------------------------------------
// Version
// 1.0.0 2017/04/14 初版
// ----------------------------------------------------------------------------
// [Blog]   : http://triacontane.blogspot.jp/
// [Twitter]: https://twitter.com/triacontane/
// [GitHub] : https://github.com/triacontane/
//=============================================================================

/*:
* @plugindesc AutoTranslationPlugin
* @author triacontane
*
* @param FromLanguage
* @desc It is a language code that the original translation.
* @default en
*
* @param ToLanguage
* @desc This is the translation target language code.
* @default ja
*
* @param TranslateDatabase
* @desc Translate each element of the database. Translation process involves little by little in the background.
* @default OFF
*
* @param TranslateMessage
* @desc Translate the contents of the message and choose display.
* @default ON
*
* @param TranslationSwitchId
* @desc Is the switch ID translation is enabled. Specify 0 to unconditionally valid in translation.
* @default 0
*
* @param Category
* @desc Specifies the category of translation at run time.
* (Normal:general, NeuralNetwork:generalnn)
* @default general
*
* @param OutLog
* @desc Logging the request process. (ON/TEST/OFF)
* @default TEST
*
* Automatically translate messages and data during game.
* Although there is a limit to the precision because of machine translation,
* it can easily correspond to multiple languages.
* The following is the translation target.
* 1. Message of "Text display"
* 2. Choices of "Show Choice"
* 3. "Map name"
* 4. Databases (including terminology)
*
* Translation uses "Translator Text API" (Web API) of "Microsoft Azure".
* https://azure.microsoft.com/en-us/services/cognitive-services/
*
* For the language code, please refer to the following.
* https://msdn.microsoft.com/en-us/library/hh456380.aspx
*
* The translation result is accumulated in the file
* "Translations - (translation destination language code). Json"
* If the same sentence is requested, the contents saved in the file are returned.
* The JSON file is a simple structure that uses the text before translation
* as the key and the post sentence as the value
* It can be edited easily with the JSON editor etc. as follows. (Editing is self-responsibility)
*
* http://jsoneditoronline.org/
*
* The creation of the translation data is done only during the test play,
* only after releasing the JSON file
* It can be used even in offline games because it refers.
*
* Since message translation is performed at the timing of display,
* when communication occurs (only for the first time)
* It may take time to display the message on the window.
* Also, since database translation is executed little by little in the background,
* It takes time.
*
* Whether to apply the translation can be switched by designating an arbitrary switch.
* Please use it when you want to change the target language on the setting screen etc.
*
* Restriction
* 1. The free version of "Translator Text API" can translate up to 2 million characters per month.
* This is the total of all users of this plugin.
* (Probably I do not think it will exceed) I do not need to shrink the translation in particular,
* In the unlikely event it will be impossible to translate, please understand beforehand.
*
* 2. If you include control characters in sentences,
* the contents will be lost and skipping the translation.
*
* 3. We can not respond to requests on the system.
*
* 4. When "Translator Text API" terminates the service, this plug-in naturally
* It will become unusable. (I will consider alternatives)
*
* There is no plug-in command in this plug-in.
*
* This sentence was created by google translation.
*
* This plugin is released under the MIT License.
*/
/*:ja
* @plugindesc 自動翻訳プラグイン
* @author トリアコンタン
*
* @param 翻訳元言語
* @desc 翻訳元になる言語コードです。
* @default ja
*
* @param 翻訳先言語
* @desc 翻訳先になる言語コードです。
* @default en
*
* @param データベース翻訳
* @desc データベースの各要素を翻訳します。翻訳処理はバックグラウンドで少しずつ行われます。
* @default OFF
*
* @param メッセージ翻訳
* @desc メッセージ表示と選択肢表示の内容を翻訳します。
* @default ON
*
* @param 翻訳スイッチID
* @desc 翻訳が有効になるスイッチIDです。0を指定すると無条件で翻訳が有効になります。
* @default 0
*
* @param カテゴリ
* @desc 翻訳実行時のカテゴリを指定します。
* (通常:general ニューラルネットワーク:generalnn)
* @default general
*
* @param ログ出力
* @desc リクエストの経過をログ出力します。(ON/TEST/OFF)
* TESTはテストプレー時のみ出力
* @default TEST
*
* @help ゲーム中のメッセージおよびデータを自働で翻訳します。
* 機械翻訳のため精度には限界はありますが、手軽に多言語対応できます。
* 以下が翻訳対象です。
* 1. 「文章の表示」のメッセージ
* 2. 「選択肢の表示」の選択肢
* 3. 「マップ名」
* 4. 各種データベースの値(用語も含む)
*
* 翻訳は「Microsoft Azure」の「Translator Text API」(Web API)を使用しています。
* https://azure.microsoft.com/ja-jp/services/cognitive-services/
*
* 言語コードについては、以下を参照してください。
* https://msdn.microsoft.com/en-us/library/hh456380.aspx
*
* 翻訳結果は「Translations_(翻訳先言語コード).json」というファイルに蓄積され
* 同一の文章が要求された場合は、ファイルに保存されている内容を返します。
* JSONファイルは、翻訳前の文章をキー、翻訳後の文章を値とする簡単な構成のため
* 以下のようなJSONエディタ等で簡単に編集できます。(編集は自己責任です)
* 誤訳を調整したり、特定の単語を翻訳しないようにすることもできます。
*
* http://jsoneditoronline.org/
*
* 翻訳データの作成はテストプレー中にのみ行われ、リリース後はJSONファイルのみを
* 参照するので、オフラインゲームでも使用可能です。
*
* メッセージ翻訳は、表示するタイミングで行われるため、通信発生時(初回のみ)は
* ウィンドウにメッセージ表示までに時間が掛かる場合があります。
* また、データベース翻訳はバックグラウンドで少しずつ実行されるため完了までには
* 時間が掛かります。
*
* 翻訳を適用するかどうかは任意のスイッチを指定して切り替えることができます。
* 設定画面等で対象言語を切り替えたい場合に使用してください。
*
* ・制約事項
* 1. 「Translator Text API」の無料版は、1ヶ月に200万文字までしか翻訳できません。
* これは当プラグインの使用者全員の合計になります。
* (多分超えないと思うので)特に翻訳を萎縮して頂く必要はありませんが、
* 万一超過した場合は翻訳できなくなる点は予めご了承ください。
*
* 2. 文章に制御文字を含む場合は、内容が失われるため翻訳をスキップします。
*
* 3. 制度に関するご要望にはお応えできません。
*
* 4. 「Translator Text API」がサービスを終了した場合、当然このプラグインは
* 使用できなくなります。(代替案は検討します)
*
* このプラグインにはプラグインコマンドはありません。
*
* 利用規約:
*  作者に無断で改変、再配布が可能で、利用形態(商用、18禁利用等)
*  についても制限はありません。
*  このプラグインはもうあなたのものです。
*/

var $dataTransDic = null;

function TranslationManager() {
    throw new Error('This is a static class');
}

(function() {
    'use strict';
    var pluginName = 'AutoTranslation';

    //=============================================================================
    // ローカル関数
    //  プラグインパラメータやプラグインコマンドパラメータの整形やチェックをします
    //=============================================================================
    var getParamString = function(paramNames) {
        if (!Array.isArray(paramNames)) paramNames = [paramNames];
        for (var i = 0; i < paramNames.length; i++) {
            var name = PluginManager.parameters(pluginName)[paramNames];
            if (name) return name;
        }
        return '';
    };

    var getParamNumber = function(paramNames, min, max) {
        var value = getParamString(paramNames);
        if (arguments.length < 2) min = -Infinity;
        if (arguments.length < 3) max = Infinity;
        return (parseInt(value) || 0).clamp(min, max);
    };

    var getParamBoolean = function(paramNames) {
        var value = getParamString(paramNames);
        return value.toUpperCase() === 'ON';
    };

    //=============================================================================
    // パラメータの取得と整形
    //=============================================================================
    var param                 = {};
    param.toLanguage          = getParamString(['ToLanguage', '翻訳先言語']);
    param.fromLanguage        = getParamString(['FromLanguage', '翻訳元言語']);
    param.outLog              = getParamString(['OutLog', 'ログ出力']).toUpperCase();
    param.translationSwitchId = getParamNumber(['TranslationSwitchId', '翻訳スイッチID'], 0);
    param.translateDatabase   = getParamBoolean(['TranslateDatabase', 'データベース翻訳']);
    param.translateMessage    = getParamBoolean(['TranslateMessage', 'メッセージ翻訳']);
    param.category            = getParamString(['Category', 'カテゴリ']);

    //=============================================================================
    // Game_Interpreter
    //  文章の表示等の命令に翻訳を挟みます。
    //=============================================================================
    var _Game_Interpreter_command101      = Game_Interpreter.prototype.command101;
    Game_Interpreter.prototype.command101 = function() {
        _Game_Interpreter_command101.apply(this, arguments);
        if (param.translateMessage) {
            $gameMessage.translateMessage();
        }
    };

    var _Game_Interpreter_setupChoices      = Game_Interpreter.prototype.setupChoices;
    Game_Interpreter.prototype.setupChoices = function(params) {
        _Game_Interpreter_setupChoices.apply(this, arguments);
        if (param.translateMessage) {
            $gameMessage.translateChoice();
        }
    };

    //=============================================================================
    // Game_System
    //  翻訳先言語によって言語情報を変更します。
    //=============================================================================
    var _Game_System_isJapanese = Game_System.prototype.isJapanese;
    Game_System.prototype.isJapanese = function() {
        return this.isTranslateLocale(_Game_System_isJapanese, /^ja/);
    };

    var _Game_System_isChinese = Game_System.prototype.isChinese;
    Game_System.prototype.isChinese = function() {
        return this.isTranslateLocale(_Game_System_isChinese, /^zh/);
    };

    var _Game_System_isKorean = Game_System.prototype.isKorean;
    Game_System.prototype.isKorean = function() {
        return this.isTranslateLocale(_Game_System_isKorean, /^ko/);
    };

    var _Game_System_isCJK = Game_System.prototype.isCJK;
    Game_System.prototype.isCJK = function() {
        return this.isTranslateLocale(_Game_System_isCJK, /^(ja|zh|ko)/);
    };

    var _Game_System_isRussian = Game_System.prototype.isRussian;
    Game_System.prototype.isRussian = function() {
        return this.isTranslateLocale(_Game_System_isRussian, /^ru/);
    };

    Game_System.prototype.isTranslateLocale = function(originalMethod, ragExp) {
        if (TranslationManager.isValidTranslation()) {
            return param.toLanguage.match(ragExp);
        } else {
            return originalMethod.apply(this, arguments);
        }
    };

    //=============================================================================
    // Game_Message
    //  メッセージの翻訳処理を実行します。
    //=============================================================================
    Game_Message.prototype.translateMessage = function() {
        this._translateMessage = true;
        TranslationManager.getTranslatePromise(this.getTranslateMessage()).then(this.setTranslationMessage.bind(this));
    };

    Game_Message.prototype.translateChoice = function() {
        this._translateChoice = true;
        var promise;
        var translatedChoices = [];
        var originalChoice    = "";
        this._choices.forEach(function(choice) {
            if (!promise) {
                originalChoice = choice;
                promise        = TranslationManager.getTranslatePromise(choice);
            } else {
                promise = promise.then(function(translatedChoice) {
                    translatedChoices.push(translatedChoice || originalChoice);
                    originalChoice = choice;
                    return TranslationManager.getTranslatePromise(choice);
                });
            }
        }, this);
        promise.then(function(translatedChoice) {
            translatedChoices.push(translatedChoice || originalChoice);
            if (TranslationManager.isValidTranslation()) {
                this._choices = translatedChoices;
            }
            this._translateChoice = false;
        }.bind(this));
    };

    Game_Message.prototype.setTranslationMessage = function(translatedText) {
        if (translatedText && TranslationManager.isValidTranslation()) {
            this._texts = [translatedText];
        }
        this._translateMessage = false;
    };

    Game_Message.prototype.getTranslateMessage = function() {
        return this._texts.join('')
    };

    Game_Message.prototype.isTranslating = function() {
        return this._translateMessage || this._translateChoice;
    };

    //=============================================================================
    // Game_Actor
    //  言語が変わった場合にプロフィールを再設定します。
    //=============================================================================
    Game_Actor.prototype.reloadDatabase = function() {
        var actor      = this.actor();
        this._name     = actor.name;
        this._nickname = actor.nickname;
        this._profile  = actor.profile;
    };

    //=============================================================================
    // Window_Message
    //  翻訳中の待機と自動改行を実装します。
    //=============================================================================
    var _Window_Message_updateLoading      = Window_Message.prototype.updateLoading;
    Window_Message.prototype.updateLoading = function() {
        return _Window_Message_updateLoading.apply(this, arguments) || $gameMessage.isTranslating();
    };

    var _Window_Message_processNormalCharacter      = Window_Base.prototype.processNormalCharacter;
    Window_Message.prototype.processNormalCharacter = function(textState) {
        _Window_Message_processNormalCharacter.apply(this, arguments);
        if (TranslationManager.isValidTranslation()) {
            this.processAutoWordWrap(textState);
        }
    };

    Window_Message.prototype.processAutoWordWrap = function(textState) {
        var c         = textState.text[textState.index];
        var textNextX = textState.x + (c ? this.textWidth(c) : 0);
        if (textNextX > this.contents.width) {
            textState.index--;
            this.processNewLine(textState);
        }
    };

    //=============================================================================
    // TranslationManager
    //  翻訳の実行を管理します。
    //=============================================================================
    TranslationManager._accessTokenUrl   = 'https://api.cognitive.microsoft.com/sts/v1.0/issueToken';
    TranslationManager._translateUrl     = 'https://api.microsofttranslator.com/V2/Http.svc/Translate';
    TranslationManager._subscriptionKey1 = 'f78dab007fdb4ad4ad5baaaa01b74829';

    TranslationManager._translateProperties = {
        $dataActors : ['name', 'nickname', 'profile'],
        $dataClasses: ['name'],
        $dataSkills : ['name', 'description', 'message1', 'message2'],
        $dataItems  : ['name', 'description', 'message1', 'message2'],
        $dataWeapons: ['name', 'description'],
        $dataArmors : ['name', 'description'],
        $dataEnemies: ['name'],
        $dataStates : ['name', 'message1', 'message2', 'message3', 'message4'],
    };

    TranslationManager._translateTypeProperties = [
        'elements', 'equipTypes', 'skillTypes', 'weaponTypes', 'armorTypes'
    ];

    TranslationManager.initialize = function() {
        if (this.isMakingDictionary()) {
            this.addCloseListener();
        }
    };

    TranslationManager.makeTranslator = function() {
        this._databaseTranslator = this.translateAllDatabase();
        this._interval           = 0;
    };

    TranslationManager.clearTranslator = function() {
        this._databaseTranslator = null;
        this._interval           = -1;
    };

    TranslationManager.isExistTranslator = function() {
        return !!this._databaseTranslator;
    };

    TranslationManager.refreshData = function() {
        if ($gameActors) {
            $gameActors._data.forEach(function(actor) {
                if (actor) actor.reloadDatabase();
            })
        }
    };

    TranslationManager.update = function() {
        if (this._interval === 0 && this._databaseTranslator && !this._translateError) {
            var result = this._databaseTranslator.next();
            if (result.done) {
                this._interval = -1;
            } else {
                this._interval = 120;
            }
        } else if (this._interval > 0) {
            this._interval--;
        }
        if (this.isValidTranslation() !== this._prevValidTranslation) {
            this._prevValidTranslation = this.isValidTranslation();
            this.refreshData();
        }
    };

    // Generator Function
    TranslationManager.translateAllDatabase = function*() {
        var i, j;
        this._currentData = $dataSystem;
        if (!this.translateProperty('gameTitle')) {
            yield;
        }

        for (i = 0; i < this._translateTypeProperties.length; i++) {
            this._currentData = $dataSystem[this._translateTypeProperties];
            for (j = 0; j < this._currentData.length; j++) {
                if (!this.translateProperty(j)) {
                    yield;
                }
            }
        }

        var termNames = Object.keys($dataSystem.terms);
        for (i = 0; i < termNames.length; i++) {
            this._currentData = $dataSystem.terms[termNames];
            var isArray       = Array.isArray(this._currentData);
            var keyArray      = (isArray ? this._currentData : Object.keys(this._currentData));
            for (j = 0; j < keyArray.length; j++) {
                if (!this.translateProperty(isArray ? j : keyArray[j])) {
                    yield;
                }
            }
        }

        var databaseNames = Object.keys(this._translateProperties);
        for (i = 0; i < databaseNames.length; i++) {
            var databaseName = databaseNames;
            for (j = 1; j < window[databaseName].length; j++) {
                this._currentData = window[databaseName][j];
                if (!this.translateProperties(this._translateProperties[databaseName])) {
                    yield;
                }
            }
        }
    };

    TranslationManager.translateProperties = function(properties) {
        return properties.every(function(property) {
            return this.translateProperty(property);
        }, this);
    };

    TranslationManager.translateProperty = function(propertyName) {
        if (this._translating) return false;
        var targetText = this._currentData[propertyName + 'Original'] || this._currentData[propertyName];
        this._continue = true;
        this.translateIfNeed(targetText, this.setTranslatedData.bind(this, propertyName));
        return this._continue;
    };

    TranslationManager.setTranslatedData = function(propertyName, translatedText) {
        var originalProperty = propertyName + 'Original';
        if (!translatedText || this._currentData.hasOwnProperty(originalProperty)) return;
        this._currentData[originalProperty] = this._currentData[propertyName];
        Object.defineProperty(this._currentData, propertyName, {
            get         : function() {
                if (TranslationManager.isValidTranslation()) {
                    return translatedText;
                } else {
                    return this[originalProperty];
                }
            },
            configurable: false
        });
    };

    TranslationManager.translateIfNeed = function(targetText, callBack) {
        var dictionaryText = $dataTransDic[targetText];
        if (dictionaryText) {
            callBack(dictionaryText);
            return;
        }
        if (this.isInvalidText(targetText) || !this.isMakingDictionary()) {
            callBack(null);
            return;
        }
        this._translating = true;
        this.requestExecute(targetText).then(function(translatedText) {
            translatedText = this.parseTranslatedText(translatedText);
            this.addDictionary(targetText, translatedText);
            this._translating = false;
            callBack(translatedText);
        }.bind(this), function() {
            this._translateError = true;
            callBack(null);
        }.bind(this));
        this._continue = false;
    };

    TranslationManager.getTranslatePromise = function(targetText) {
        return new Promise(function(resolve) {
            this.translateIfNeed(targetText, resolve);
        }.bind(this));
    };

    TranslationManager.isInvalidText = function(targetText) {
        return !targetText || this.isExistControlCharacter(targetText)
    };

    TranslationManager.parseTranslatedText = function(translatedText) {
        translatedText = translatedText.replace(/%\s+(\d+)/gi, function() {
            return '%' + arguments[1] + ' ';
        }.bind(this));
        return translatedText;
    };

    TranslationManager.addDictionary = function(targetText, translatedText) {
        $dataTransDic[targetText] = translatedText;
    };

    TranslationManager.requestExecute = function(text) {
        return this.requestAccessToken().then(this.requestTranslate.bind(this, text));
    };

    TranslationManager.requestAccessToken = function() {
        var client = new Game_PostWebClient(this._accessTokenUrl);
        client.addRequestHeader('Ocp-Apim-Subscription-Key', this._subscriptionKey1);
        return client.request();
    };

    TranslationManager.requestTranslate = function(text, accessToken) {
        var client = new Game_GetWebClient(this._translateUrl);
        client.setLogPolicy(param.outLog);
        client.addQuery('appid', `Bearer ${accessToken}`);
        client.addQuery('text', text);
        client.addQuery('from', param.fromLanguage);
        client.addQuery('to', param.toLanguage);
        client.addQuery('category', param.category || 'general');
        return client.request().then(this.parseResponse.bind(this));
    };

    TranslationManager.parseResponse = function(resultXml) {
        var parser = new DOMParser();
        var dom    = parser.parseFromString(resultXml, 'text/xml');
        return dom.getElementsByTagName('string').item(0).textContent;
    };

    TranslationManager.addCloseListener = function() {
        var nwWin = require('nw.gui').Window.get();
        nwWin.on('close', function() {
            try {
                DataManager.saveTranslateData();
            } finally {
                nwWin.close(true);
            }
        });
    };

    TranslationManager.isExistControlCharacter = function(targetText) {
        return targetText.match(/\\/);
    };

    TranslationManager.isMakingDictionary = function() {
        return Utils.isNwjs() && Utils.isOptionValid('test');
    };

    TranslationManager.isValidTranslation = function() {
        return param.translationSwitchId && $gameSwitches ? $gameSwitches.value(param.translationSwitchId) : true;
    };

    //=============================================================================
    // SceneManager
    //  TranslationManagerの初期化と更新を行います。
    //=============================================================================
    var _SceneManager_initialize = SceneManager.initialize;
    SceneManager.initialize      = function() {
        _SceneManager_initialize.apply(this, arguments);
        TranslationManager.initialize();
    };

    var _SceneManager_updateManagers = SceneManager.updateManagers;
    SceneManager.updateManagers      = function() {
        _SceneManager_updateManagers.apply(this, arguments);
        if ($dataTransDic && param.translateDatabase) {
            TranslationManager.update();
        }
    };

    //=============================================================================
    // DataManager
    //  辞書データのロードとセーブを実装します。
    //=============================================================================
    DataManager._languageFileUrl = `data/Translations_${param.toLanguage}.json`;

    var _DataManager_loadDatabase = DataManager.loadDatabase;
    DataManager.loadDatabase      = function() {
        _DataManager_loadDatabase.apply(this, arguments);
        if (!$dataTransDic) {
            this.loadTranslateData();
        }
        TranslationManager.clearTranslator();
    };

    DataManager.loadTranslateData = function() {
        var client = new Game_GetWebClient(this._languageFileUrl);
        client.request().then(this.onLoadLanguageData, this.onErrorLanguageData);
    };

    DataManager.onLoadLanguageData = function(data) {
        $dataTransDic = JSON.parse(data);
    };

    DataManager.onErrorLanguageData = function() {
        console.log('Make Dictionary JSON file.');
        $dataTransDic = {};
    };

    DataManager.saveTranslateData = function() {
        if (!$dataTransDic) return;
        StorageManager.saveTranslateFile(this._languageFileUrl, JSON.stringify($dataTransDic));
    };

    var _DataManager_isDatabaseLoaded = DataManager.isDatabaseLoaded;
    DataManager.isDatabaseLoaded      = function() {
        var result = _DataManager_isDatabaseLoaded.apply(this, arguments) && !!$dataTransDic;
        if (result && !TranslationManager.isExistTranslator()) {
            TranslationManager.makeTranslator();
            if (TranslationManager.isMakingDictionary()) {
                this.checkCanSaveDictionary();
            }
        }
        return result;
    };

    DataManager.checkCanSaveDictionary = function() {
        try {
            this.saveTranslateData();
        } catch (e) {
            throw new Error('Failed To Save Dictionary file. 辞書ファイルを開いている可能性があります。');
        }
    };

    if (param.translateDatabase) {
        var _DataManager_loadMapData = DataManager.loadMapData;
        DataManager.loadMapData      = function(mapId) {
            _DataManager_loadMapData.apply(this, arguments);
            this._mapNameLoadingStatus = 1;
        };

        var _DataManager_isMapLoaded = DataManager.isMapLoaded;
        DataManager.isMapLoaded      = function() {
            var loaded = _DataManager_isMapLoaded.apply(this, arguments);
            if (loaded && this._mapNameLoadingStatus === 1) {
                this._mapNameLoadingStatus = 2;
                TranslationManager.getTranslatePromise($dataMap.displayName).then(this.onTranslateDisplayName.bind(this));
            }
            return loaded && this._mapNameLoadingStatus === 3;
        };

        DataManager.onTranslateDisplayName = function(translatedDisplayName) {
            if (TranslationManager.isValidTranslation()) {
                $dataMap.displayName = translatedDisplayName;
            }
            this._mapNameLoadingStatus = 3;
        };
    }

    //=============================================================================
    // StorageManager
    //  辞書データをファイルにして保存します。
    //=============================================================================
    StorageManager.saveTranslateFile = function(filePath, json) {
        var fs   = require('fs');
        var path = require('path');
        var base = path.dirname(process.mainModule.filename);
        fs.writeFileSync(path.join(base, filePath), json);
    };

    //=============================================================================
    // Game_BaseWebClient
    //  WebAPIに対してリクエストを投げる基底クラスです。
    //=============================================================================
    class Game_BaseWebClient {
        constructor(url) {
            this._xmlHttpRequest = new XMLHttpRequest();
            this._xmlHttpRequest.addEventListener('readystatechange', this.onReadyStateChange.bind(this));
            this._originalUrl    = url;
            this._requestHeaders = {};
            this._queryParams    = {};
            this.setLogPolicy('OFF');
            this.setResponseType('text');
            this.setTimeout(20000);
        }

        setTimeout(timeout) {
            this._timeout = timeout;
        }

        setResponseType(type) {
            this._responseType = type;
        }

        setLogPolicy(policy) {
            this._logPolicy = policy;
        }

        getFullUrl() {
            return this._originalUrl;
        }

        getRequestMethodName() {
            return '';
        }

        getSendQuery() {
            return undefined;
        }

        request() {
            var xhr = this._xmlHttpRequest;
            xhr.open(this.getRequestMethodName(), this.getFullUrl());
            this.setRequestHeaders();
            xhr.responseType = this._responseType;
            xhr.timeout      = this._timeout;
            xhr.send(this.getSendQuery());
            return this.getPromise();
        }

        getPromise() {
            return new Promise(function(resolve, reject) {
                this._xmlHttpRequest.addEventListener('load', this.onLoad.bind(this, resolve, reject));
                this._xmlHttpRequest.addEventListener('error', this.onError.bind(this, reject));
            }.bind(this));
        }

        addRequestHeader(name, value) {
            this._requestHeaders[name] = value;
        }

        addQuery(name, value) {
            this._queryParams[name] = value;
        }

        getQueryText() {
            var paramArray = [];
            var keys       = Object.keys(this._queryParams);
            if (keys && keys.length > 0) {
                keys.forEach(function(paramName) {
                    paramArray.push(encodeURIComponent(paramName) + '=' + encodeURIComponent(this._queryParams[paramName]));
                }, this);
            }
            return paramArray.join('&');
        }

        setRequestHeaders() {
            var keys = Object.keys(this._requestHeaders);
            if (keys && keys.length > 0) {
                keys.forEach(function(paramName) {
                    this._xmlHttpRequest.setRequestHeader(paramName, this._requestHeaders[paramName]);
                }, this);
            }
        }

        onReadyStateChange() {
            var xhr = this._xmlHttpRequest;
            this.outputDebugLog(`${xhr.readyState} : ${this.getReadyStateMessage()}`);
            if (xhr.readyState < 4) return;
            if (this.isStatusOk()) {
                this.outputDebugLog(this.getResponse());
            } else {
                this.outputErrorLog(this.getResponse());
            }
        }

        onLoad(resolve, reject) {
            if (this.isStatusOk()) {
                resolve(this.getResponse());
            } else {
                reject(this.getResponse());
            }
        }

        onError(reject) {
            reject(this.getResponse());
        }

        getReadyStateMessage() {
            var xhr   = this._xmlHttpRequest;
            var value = '';
            switch (xhr.readyState) {
                case 0:
                    value = 'Before Open';
                    break;
                case 1:
                    value = 'Before Send [URL]' + this.getFullUrl();
                    break;
                case 2:
                    value = 'After Send [Parameter]' + (this.getSendQuery() || '');
                    break;
                case 3:
                    value = 'Processing...';
                    break;
                case 4:
                    value = (this.isStatusOk() ? 'Success' : 'Failure') + '[Code]' + xhr.status;
                    break;
            }
            return value;
        }

        getResponse() {
            var xhr = this._xmlHttpRequest;
            switch (this._responseType) {
                case '':
                case 'text':
                    return xhr.responseText;
                case 'xml':
                    return xhr.responseXML;
                default:
                    return xhr.response;
            }
        }

        isStatusOk() {
            return this._xmlHttpRequest.status < 400;
        }

        showDevToolsIfNeed() {
            var nwWin = require('nw.gui').Window.get();
            if (!nwWin.isDevToolsOpen()) {
                var devTool = nwWin.showDevTools();
                devTool.moveTo(0, 0);
                devTool.resizeTo(window.screenX + window.outerWidth, window.screenY + window.outerHeight);
                nwWin.focus();
            }
        }

        outputDebugLog(value) {
            if (this.isNeedDebugLog()) {
                console.log(value);
            }
        }

        outputErrorLog(value) {
            if (this.isNeedDebugLog()) {
                this.showDevToolsIfNeed();
            }
            console.warn(value);
        }

        isNeedDebugLog() {
            switch (this._logPolicy) {
                case 'ON':
                    return true;
                case 'TEST':
                    return Utils.isOptionValid('test');
                default :
                    return false;
            }
        }
    }

    //=============================================================================
    // Game_GetWebClient
    //  WebAPIに対してGETリクエストを投げるクラスです。
    //=============================================================================
    class Game_GetWebClient extends Game_BaseWebClient {
        getRequestMethodName() {
            return 'GET';
        }

        getFullUrl() {
            var queryText = this.getQueryText();
            return super.getFullUrl() + (queryText.length > 0 ? '?' + queryText : '');
        }
    }

    //=============================================================================
    // Game_PostWebClient
    //  WebAPIに対してPOSTリクエストを投げるクラスです。
    //=============================================================================
    class Game_PostWebClient extends Game_BaseWebClient {
        getRequestMethodName() {
            return 'POST';
        }

        getSendQuery() {
            return this.getQueryText();
        }
    }
})();

[/pre]
回复

使用道具 举报

梦石
0
星屑
50
在线时间
0 小时
注册时间
2017-5-25
回帖
1
发表于 2017-5-25 22:06:18 | 显示全部楼层
请问能介绍一下使用方法吗?我放到了JS下面但是似乎没有生效,是不是还需要先配置JS?

点评

基本除要設定翻訳的語言(予設是翻訳成日文),前提是要能連線到https://azure.microsoft.com/ja-jp/services/cognitive-services/,和翻訳量未到上限  发表于 2017-5-27 19:43
回复

使用道具 举报

梦石
0
星屑
15294
在线时间
720 小时
注册时间
2011-7-16
回帖
1373

开拓者

发表于 2017-5-27 13:23:57 | 显示全部楼层
学习了,太过强大,一时半会还消化不了
RMMV网络插件,开源免费,内含服务器端,无需强制登录,云数据,弹幕,云存档,排名,兑换码,版本检测,可自由上架下架删除。q群399090587
免打包运行MV游戏,云游戏,安卓App雷神游戏厅,在线玩游戏,上传下载游戏
开源游戏:重装机兵之重装归来【RMMV制作】全球首款按照美剧分季分集的方式发布的游戏
体素画 -- MV画3D像素图的画板
RMMV显示3D模型和场景的插件
RMMV显示spine骨骼动画的插件
RMMV秘密通道插件
突破敌群数量上限8个的插件
在rmmv中显示gif动态图片的插件
一款可以在mv游戏界面的任意位置显示任意文字的插件
RMMV Toast 插件 带物品得失提示,可以设置开启关闭 兼容yep itemcore
制作一个改名卡道具插件、调整标题页面菜单的插件、在标题页面之前显示大段文字的插件、标题页面显示版本号的插件
物品得失自动提示自动上色自动换行插件
我的Q群 663889472
另外,我的插件、范例、游戏都在这里
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

Powered by Discuz! X5.0 © 2001-2026 Discuz! Team.

在本版发帖返回顶部