Greasy Fork is available in English.

Strategry Import/Export on Stake|Stake策略导入导出

Import and export dice strategy on Stake.Contact @fcfcface via telegram for more tools.通过Telegram联系@fcfcface获取更多工具。

// ==UserScript==
// @name         Strategry Import/Export on Stake|Stake策略导入导出
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  Import and export dice strategy on Stake.Contact @fcfcface via telegram for more tools.通过Telegram联系@fcfcface获取更多工具。
// @author       FCFC
// @match        https://stake.com/zh/casino/games/dice
// @icon         https://www.google.com/s2/favicons?sz=64&domain=stake.com
// @match        https://stake.com/*
// @match        https://stake.ac/*
// @match        https://stake.games/*
// @match        https://stake.bet/*
// @match        https://stake.pet/*
// @match        https://stake.mba/*
// @match        https://stake.jp/*
// @match        https://stake.bz/*
// @match        https://stake.ceo/*
// @match        https://stake.krd/*
// @match        https://staketr.com/*
// @match        https://stake1001.com/*
// @match        https://stake1002.com/*
// @match        https://stake1003.com/*
// @match        https://stake1021.com/*
// @match        https://stake.us/*
// @require      https://code.jquery.com/jquery-3.7.1.min.js
// @grant        GM_getResourceText
// @grant        GM_addStyle
// @require      https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/codemirror.min.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/mode/javascript/javascript.min.js
// @resource     codemirrorCSS https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/codemirror.min.css
// @resource     codemirrorthemeCSS https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.5/theme/dracula.min.css
// ==/UserScript==

(function() {
    'use strict';

    // 获取CSS内容
    const css = GM_getResourceText("codemirrorCSS");
    const css1 = GM_getResourceText("codemirrorthemeCSS");

    // 添加到页面样式中
    GM_addStyle(css);
    GM_addStyle(css1);

    var $ = $ || window.$;
    $(function(){
        var botName = GM_info.script.name;
        var version = GM_info.script.version;
        var storeKey = 'strategies_saved';
        var list = [];
        var selectedList = [];
        var editor = null;
        var storage = {
            get: async(key) => {
                try {
                    const res = localStorage.getItem(key);
                    return JSON.parse(res);
                } catch(error) {
                    throw error;
                }
            },
            set: async(key, data) => {
                try {
                    let datastr = JSON.stringify(data);
                    localStorage.setItem(key, datastr);
                } catch(error) {
                    throw error;
                }
            }
        }
        var language = {
            zh: {
                showBotLabel: '策略管理',
                botName: '策略导入导出',
                export: '导出',
                import: '导入',
                selectStra: '选择要导出的策略',
                selectFile: '从JSON文件导入',
                fileError: '文件解析错误。',
                ImportNotFound: '请选选择json文件或者粘贴json内容。',
                importSuccess: '已导入,请刷新页面。',
                exportNotFound: '请先选择要导出的策略。',
                exportSuccess: '已导出,请查看浏览器下载列表。',
            },
            en: {
                showBotLabel: 'Strategy',
                botName: 'Strategy Import/Export',
                export: 'Export',
                import: 'Import',
                selectStra: 'Select the strategy to export',
                selectFile: 'Import from json file',
                fileError: 'File parsing error.',
                ImportNotFound: 'Please select the json file or paste the json content.',
                importSuccess: 'mported, please refresh the page.',
                exportNotFound: 'Please select the strategy you want to export first.',
                exportSuccess: 'Exported, please check the browser download list.',
            }
        }
        var locale = window.location.href.indexOf('/zh') > -1 ? 'zh' : 'en';
        var i18n = locale == 'zh' ? language.zh : language.en;
        init();
        async function init() {
            await UI();
            // 初始化 CodeMirror 编辑器
            let target = $('#strategyWrap .editor textarea')[0];
            editor = CodeMirror.fromTextArea(target, {
                mode: { name: "javascript", json: true },
                lineNumbers: true,
                //theme: "default",
                theme: "dracula", // 设置黑暗主题
                tabSize: 2,
            });
            editor.setSize("100%", "300px");
            await getList();
            exportStrategy();
            chooseFile();
            importStrategy();
        }
        async function getList() {
            try {
                list = await storage.get(storeKey);
                const straList = [];
                let renderList = '';
                list.forEach((item, index) => {
                    straList.push({name: item.label, index});
                    renderList+= `<div class="strategy-item">${item.label}</div>`
                })
                $('#strategyWrap .strategy').html(renderList);
                // 获取所选项的值
                $('#strategyWrap .strategy-item').click(function(e) {
                    let index = $(this).index();
                    let name = $(this).text();
                    //console.log('Index:' + index);
                    let active = $(this).hasClass('stra-item-active');
                    let select = !active;
                    if (select) {
                        $(this).addClass('stra-item-active');
                        selectedList.push(list[index]);
                    } else {
                        //console.log('取消选择:' + name);
                        $(this).removeClass('stra-item-active');
                        const newSelectList = [];
                        selectedList.forEach(item => {
                            if (item.label != name) {
                                newSelectList.push(item);
                            }
                        });
                        selectedList = newSelectList;
                    }
                    //console.log(selectedList)
                    //editor.setValue(JSON.stringify(selectedList, null, 2));
                })
            } catch(error) {
                message(error.message, 'error');
            }
        }
        function chooseFile() {
            document.getElementById('json-input').addEventListener('change', function(event) {
                const file = event.target.files[0];

                if (file) {
                    const reader = new FileReader();
                    reader.onload = function(e) {
                        try {
                            // 将文件内容解析为 JSON 对象
                            const jsonData = JSON.parse(e.target.result);
                            editor.setValue(JSON.stringify(jsonData, null, 2));
                        } catch (error) {
                            console.error("文件解析错误:", error);
                            message(i18n.fileError, 'error');
                        }
                    };
                    reader.readAsText(file); // 读取文件内容
                }
            });
        }
        function importStrategy() {
            $('#strategyWrap .import-btn').click(async function(){
                try {
                    const content = editor.getValue();
                    if (!content || !content.toString || content.toString() == '[]' || content.toString() == '{}') {
                        message(i18n.ImportNotFound);
                        return;
                    }
                    const newList = JSON.parse(content); // 解析 JSON 验证格式
                    const oldList = await storage.get(storeKey);
                    const oldlabels = [];
                    oldList.forEach(item => {
                        oldlabels.push(item.label);
                    })
                    newList.forEach((item,index) => {
                        if (oldlabels.includes(item.label)) {
                            newList[index].label = `${item.label}-1`;
                        }
                    })
                    oldList.push(...newList);
                    // 保存策略
                    await storage.set(storeKey, oldList);
                    message(i18n.importSuccess, 'success');
                    editor.setValue("");
                } catch(error) {
                    message(error.message, 'error');
                }
            })
        }
        function exportStrategy() {
            $('#strategyWrap .export-btn').click(function() {
                if (selectedList.length == 0) {
                    message(i18n.exportNotFound);
                    return;
                }
                selectedList.map(item => {
                    item.label = `${item.label}`;
                    return item;
                })
                const filename = 'export_strategy.json';
                // 将 JSON 对象转为字符串
                const jsonStr = JSON.stringify(selectedList, null, 2);

                // 创建 Blob 对象
                const blob = new Blob([jsonStr], { type: "application/json" });

                // 创建下载链接
                const link = document.createElement("a");
                link.href = URL.createObjectURL(blob);
                link.download = filename;

                // 触发下载
                link.click();

                // 释放 URL 对象
                URL.revokeObjectURL(link.href);
                message(i18n.exportSuccess, 'success');
            })
        }
        function message(text, type) {
            let msgHtml = '';
            let successColor = '#00e701';
            let errorColor = 'red';
            if (type == 'success') {
                msgHtml = `<div style="color: ${successColor}">${text}</div>`;
            } else if (type == 'error') {
                msgHtml = `<div style="color: ${errorColor}">${text}</div>`;
            } else {
                msgHtml = `<div style="color:#e3a725">${text}</div>`;
            }
            $('#strategyWrap .error-message-wrap').html(msgHtml);
        }
        async function UI() {
            // 获取窗口宽度
            var windowWidth = $(window).width();
            //console.log("初始窗口宽度: " + windowWidth);
            let wrapWidth = windowWidth > 640 ? '480px' : '86%';
            let wrapLeft = windowWidth > 640 ? '60px' : '7%';
            let showCenter = windowWidth > 640 ? 'left:50%;margin-left:-240px;' : '';
            //const style = document.createElement('style');
            //style.type = 'text/css';
            // style.innerHTML
            const CSS = `#strategyWrap {font-size:13px;color:#d5dceb;}
        #strategy-status {position:fixed;right: 0;top:136px;width:62px;height:30px;text-align:center;line-height:30px;background:#1475E1;color:#fff;font-size:12px;cursor:pointer;z-index:1000001;border-top-left-radius: 16px;
    border-bottom-left-radius: 16px;}
        #strategyWrap .get-balance-btn {padding: 0 5px;height: 30px;border-radius: 4px;background: #1475E1;color:#fff;font-size:0.7rem;cursor:no-drop;opacity:0.6;}
        #strategyWrap .import-btn {display:flex;align-items:center;justify-content: center;padding: 0 8px;height:26px;background:#996d0e;border-radius:4px;cursor:pointer;}
        #strategyWrap .export-btn {display:flex;align-items:center;justify-content: center;padding: 0 8px;height:26px;background:#158922;border-radius:4px;cursor:pointer;}
        #strategyWrap .strategy {background:#1a2c38;padding:5px;border:1px solid #2f4553;border-radius:5px;max-height:100px;overflow:auto;}
        #strategyWrap .strategy .strategy-item {display:inline-block;line-height:26px;padding:0 8px;height:26px;border:1px solid #2f4553;margin:5px;border-radius:5px;cursor:pointer;}
        .stra-item-active {background: #1f5b9f}
        #strategyWrap .error-message-wrap {background:#1a2c38;padding:10px;border:1px solid #2f4553;border-radius:5px;min-height:35px;max-height:60px;overflow:auto;margin-top:5px;}
    `;
            GM_addStyle(CSS);
            // 将样式元素添加到页面头部
            //document.head.appendChild(style);
            var html = `<div id="strategy-status">${i18n.showBotLabel}</div>
                <div id="strategyWrap" style="position:fixed;top:72px;left:${wrapLeft};z-index:1000000;background:rgba(0,0,0,.5);border-radius:5px;width:${wrapWidth};${showCenter}">
                    <div style="padding:10px 8px;background:#213743;margin:0 auto;border-radius:5px;border:2px solid #2f4553;">
                         <div style="display:flex;align-items:center;justify-content: space-between;">
                             <div style="font-size:16px;font-weight:bold;color:#fff">${i18n.botName} <span class="version">v${version}</span></div>
                         </div>
                         <div class="export" style="margin:10px 0;">
                             <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:5px;">
                                 <div style="margin-bottom:5px;font-size:14px;font-weight:bold;color:#fff;">${i18n.selectStra}</div>
                                 <div class="export-btn">${i18n.export}</div>
                             </div>
                             <div class="strategy"></div>
                         </div>
                         <div class="import" style="margin-top:10px;">
                             <div style="display:flex;align-items:center;justify-content:space-between;">
                                 <div style="margin-bottom:5px;font-size:14px;font-weight:bold;color:#fff;">${i18n.selectFile}</div>
                                 <div class="import-btn">${i18n.import}</div>
                             </div>
                             <input type="file" id="json-input" accept=".json" />
                         </div>
                         <div class="editor" style="margin-top:8px;overflow:hidden;border-radius:5px;border:1px solid #2f4553;">
                             <textarea></textarea>
                         </div>

                         <div class="error-message-wrap"></div>
                     </div>
               </div>`
            $('body').append(html);

            $('#strategy-status').click(function(){
                $('#strategyWrap').toggle();
            })
        }
    })
})();