Commit a7073477 authored by nanahira's avatar nanahira

Merge branch 'master' into ai-play

parents 65a995d8 fd2bf6ea
Pipeline #41576 passed with stages
in 10 minutes and 11 seconds
...@@ -10,7 +10,7 @@ RUN apt update && \ ...@@ -10,7 +10,7 @@ RUN apt update && \
# windbot # windbot
RUN git clone --depth=1 https://code.mycard.moe/nanahira/windbot /tmp/windbot && \ RUN git clone --depth=1 https://code.mycard.moe/nanahira/windbot /tmp/windbot && \
cd /tmp/windbot && \ cd /tmp/windbot && \
xbuild /property:Configuration=Release /property:TargetFrameworkVersion="v4.0" && \ xbuild /property:Configuration=Release /property:TargetFrameworkVersion="v4.5" && \
mv /tmp/windbot/bin/Release /ygopro-server/windbot && \ mv /tmp/windbot/bin/Release /ygopro-server/windbot && \
cp -rf /ygopro-server/ygopro/cards.cdb /ygopro-server/windbot/ && \ cp -rf /ygopro-server/ygopro/cards.cdb /ygopro-server/windbot/ && \
rm -rf /tmp/windbot rm -rf /tmp/windbot
......
...@@ -38,7 +38,7 @@ RUN git clone --branch=server --recursive --depth=1 https://code.mycard.moe/nana ...@@ -38,7 +38,7 @@ RUN git clone --branch=server --recursive --depth=1 https://code.mycard.moe/nana
strip ygopro && \ strip ygopro && \
mkdir replay expansions && \ mkdir replay expansions && \
rm -rf .git* bin obj build ocgcore cmake lua premake* sound textures .travis.yml *.txt appveyor.yml LICENSE README.md *.lua strings.conf system.conf && \ rm -rf .git* bin obj build ocgcore cmake lua premake* sound textures .travis.yml *.txt appveyor.yml LICENSE README.md *.lua strings.conf system.conf && \
ls gframe | sed '/game.cpp/d' | xargs -I {} rm -rf gframe/{} ls gframe | sed '/config.h/d' | xargs -I {} rm -rf gframe/{}
# infos # infos
WORKDIR /ygopro-server WORKDIR /ygopro-server
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
"stop": false, "stop": false,
"full": "服务器已爆满", "full": "服务器已爆满",
"max_rooms_count": 0, "max_rooms_count": 0,
"max_mem_percentage": 95,
"side_timeout": false, "side_timeout": false,
"replay_delay": true, "replay_delay": true,
"hide_name": false, "hide_name": false,
...@@ -40,6 +41,7 @@ ...@@ -40,6 +41,7 @@
"expansions_path": [ "expansions_path": [
"./expansions" "./expansions"
], ],
"extra_script_path": [],
"i18n": { "i18n": {
"auto_pick": false, "auto_pick": false,
"default": "zh-cn", "default": "zh-cn",
...@@ -79,7 +81,8 @@ ...@@ -79,7 +81,8 @@
"get": "https://sapi.moecube.com:444/biu-tips/tips.json", "get": "https://sapi.moecube.com:444/biu-tips/tips.json",
"get_zh": false, "get_zh": false,
"interval": 30000, "interval": 30000,
"interval_ingame": 120000 "interval_ingame": 120000,
"prefix": "Tip: "
}, },
"dialogues": { "dialogues": {
"enabled": true, "enabled": true,
...@@ -118,7 +121,8 @@ ...@@ -118,7 +121,8 @@
"TMR": true "TMR": true
}, },
"ready_time": 20, "ready_time": 20,
"hang_timeout": 90 "hang_timeout": 90,
"extra_modes": {}
}, },
"mysql": { "mysql": {
"enabled": false, "enabled": false,
...@@ -245,8 +249,9 @@ ...@@ -245,8 +249,9 @@
"endpoint": "https://api.openai.com", "endpoint": "https://api.openai.com",
"token": "sk-xxxx", "token": "sk-xxxx",
"model": "gpt-4o-mini", "model": "gpt-4o-mini",
"system_prompt": "", "system_prompt": "你是{{windbot}},一名与{{player}}实时互动的游戏对手。你的回复应简短、有趣、贴合当前情境,增强玩家沉浸感。避免冗长解释或重复内容,保持自然流畅,并且每次回复不能超过100个字。",
"comment": "{{player}} and {{opponent}} will be replaced in the prompt", "comment": "{{player}} and {{windbot}} will be replaced in the prompt",
"token_limit": 12000,
"extra_opts": {} "extra_opts": {}
}, },
"test_mode": { "test_mode": {
......
...@@ -411,8 +411,8 @@ ...@@ -411,8 +411,8 @@
"bad_user_name": "请输入正确的用户名", "bad_user_name": "请输入正确的用户名",
"server_full": "服务器已经爆满,请稍候再试", "server_full": "服务器已经爆满,请稍候再试",
"too_much_connection": "同时开启的客户端数量过多 ", "too_much_connection": "同时开启的客户端数量过多 ",
"banned_ip_login": "您的账号已被封禁", "banned_ip_login": "您的账号已被封禁。如果您没有进行违规操作且用的是流量网络,可能过几小时就好。是IP撞了。",
"banned_user_login": "您的账号已被封禁", "banned_user_login": "您的账号已被封禁。如果您没有进行违规操作且用的是流量网络,可能过几小时就好。是IP撞了。",
"bad_name_level3": "您的用户名存在不适当的内容", "bad_name_level3": "您的用户名存在不适当的内容",
"bad_name_level2": "您的用户名存在不适当的内容", "bad_name_level2": "您的用户名存在不适当的内容",
"bad_name_level1": "您的用户名存在不适当的内容,请注意更改", "bad_name_level1": "您的用户名存在不适当的内容,请注意更改",
......
...@@ -16,11 +16,13 @@ ...@@ -16,11 +16,13 @@
"deepmerge": "^4.2.2", "deepmerge": "^4.2.2",
"formidable": "^1.2.6", "formidable": "^1.2.6",
"geoip-country-lite": "^1.0.0", "geoip-country-lite": "^1.0.0",
"gpt-tokenizer": "^3.0.1",
"ip6addr": "^0.2.5", "ip6addr": "^0.2.5",
"jszip": "^3.5.0", "jszip": "^3.5.0",
"load-json-file": "^6.2.0", "load-json-file": "^6.2.0",
"lzma": "^2.3.2", "lzma": "^2.3.2",
"moment": "^2.29.1", "moment": "^2.29.1",
"mustache": "^4.2.0",
"mysql": "^2.18.1", "mysql": "^2.18.1",
"node-os-utils": "^1.3.2", "node-os-utils": "^1.3.2",
"p-queue": "^6.6.2", "p-queue": "^6.6.2",
...@@ -34,7 +36,7 @@ ...@@ -34,7 +36,7 @@
"underscore": "^1.11.0", "underscore": "^1.11.0",
"underscore.string": "^3.3.6", "underscore.string": "^3.3.6",
"ws": "^8.9.0", "ws": "^8.9.0",
"ygopro-deck-encode": "^1.0.9" "ygopro-deck-encode": "^1.0.14"
}, },
"devDependencies": { "devDependencies": {
"@types/bunyan": "^1.8.8", "@types/bunyan": "^1.8.8",
...@@ -1357,6 +1359,12 @@ ...@@ -1357,6 +1359,12 @@
"url": "https://github.com/sponsors/ljharb" "url": "https://github.com/sponsors/ljharb"
} }
}, },
"node_modules/gpt-tokenizer": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/gpt-tokenizer/-/gpt-tokenizer-3.0.1.tgz",
"integrity": "sha512-5jdaspBq/w4sWw322SvQj1Fku+CN4OAfYZeeEg8U7CWtxBz+zkxZ3h0YOHD43ee+nZYZ5Ud70HRN0ANcdIj4qg==",
"license": "MIT"
},
"node_modules/graceful-fs": { "node_modules/graceful-fs": {
"version": "1.1.14", "version": "1.1.14",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.1.14.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.1.14.tgz",
...@@ -1933,6 +1941,15 @@ ...@@ -1933,6 +1941,15 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}, },
"node_modules/mustache": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz",
"integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==",
"license": "MIT",
"bin": {
"mustache": "bin/mustache"
}
},
"node_modules/mv": { "node_modules/mv": {
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz",
...@@ -3687,9 +3704,9 @@ ...@@ -3687,9 +3704,9 @@
} }
}, },
"node_modules/ygopro-deck-encode": { "node_modules/ygopro-deck-encode": {
"version": "1.0.9", "version": "1.0.14",
"resolved": "https://registry.npmjs.org/ygopro-deck-encode/-/ygopro-deck-encode-1.0.9.tgz", "resolved": "https://registry.npmjs.org/ygopro-deck-encode/-/ygopro-deck-encode-1.0.14.tgz",
"integrity": "sha512-2aw/Lr8Sg4cPXKgq71Zk/GQPTZy5GhmviptVHWqMGEW0E2qTaxwpGmsQAN2Q4OWaK1lP+3g3bZt9BaqmWYZQSw==", "integrity": "sha512-Q64f8U+okLBDKHw02eRYsdDMpALhYa55k0BhFqZ5k4ntRpPKFNvM9sNEbBlg2bmyi6LCf3rlEmISmLtlx9uDeA==",
"license": "MIT" "license": "MIT"
} }
}, },
...@@ -4678,6 +4695,11 @@ ...@@ -4678,6 +4695,11 @@
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==" "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="
}, },
"gpt-tokenizer": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/gpt-tokenizer/-/gpt-tokenizer-3.0.1.tgz",
"integrity": "sha512-5jdaspBq/w4sWw322SvQj1Fku+CN4OAfYZeeEg8U7CWtxBz+zkxZ3h0YOHD43ee+nZYZ5Ud70HRN0ANcdIj4qg=="
},
"graceful-fs": { "graceful-fs": {
"version": "1.1.14", "version": "1.1.14",
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.1.14.tgz", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-1.1.14.tgz",
...@@ -5111,6 +5133,11 @@ ...@@ -5111,6 +5133,11 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}, },
"mustache": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/mustache/-/mustache-4.2.0.tgz",
"integrity": "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ=="
},
"mv": { "mv": {
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz",
...@@ -6446,9 +6473,9 @@ ...@@ -6446,9 +6473,9 @@
} }
}, },
"ygopro-deck-encode": { "ygopro-deck-encode": {
"version": "1.0.9", "version": "1.0.14",
"resolved": "https://registry.npmjs.org/ygopro-deck-encode/-/ygopro-deck-encode-1.0.9.tgz", "resolved": "https://registry.npmjs.org/ygopro-deck-encode/-/ygopro-deck-encode-1.0.14.tgz",
"integrity": "sha512-2aw/Lr8Sg4cPXKgq71Zk/GQPTZy5GhmviptVHWqMGEW0E2qTaxwpGmsQAN2Q4OWaK1lP+3g3bZt9BaqmWYZQSw==" "integrity": "sha512-Q64f8U+okLBDKHw02eRYsdDMpALhYa55k0BhFqZ5k4ntRpPKFNvM9sNEbBlg2bmyi6LCf3rlEmISmLtlx9uDeA=="
} }
} }
} }
...@@ -18,11 +18,13 @@ ...@@ -18,11 +18,13 @@
"deepmerge": "^4.2.2", "deepmerge": "^4.2.2",
"formidable": "^1.2.6", "formidable": "^1.2.6",
"geoip-country-lite": "^1.0.0", "geoip-country-lite": "^1.0.0",
"gpt-tokenizer": "^3.0.1",
"ip6addr": "^0.2.5", "ip6addr": "^0.2.5",
"jszip": "^3.5.0", "jszip": "^3.5.0",
"load-json-file": "^6.2.0", "load-json-file": "^6.2.0",
"lzma": "^2.3.2", "lzma": "^2.3.2",
"moment": "^2.29.1", "moment": "^2.29.1",
"mustache": "^4.2.0",
"mysql": "^2.18.1", "mysql": "^2.18.1",
"node-os-utils": "^1.3.2", "node-os-utils": "^1.3.2",
"p-queue": "^6.6.2", "p-queue": "^6.6.2",
...@@ -36,7 +38,7 @@ ...@@ -36,7 +38,7 @@
"underscore": "^1.11.0", "underscore": "^1.11.0",
"underscore.string": "^3.3.6", "underscore.string": "^3.3.6",
"ws": "^8.9.0", "ws": "^8.9.0",
"ygopro-deck-encode": "^1.0.9" "ygopro-deck-encode": "^1.0.14"
}, },
"license": "AGPL-3.0", "license": "AGPL-3.0",
"scripts": { "scripts": {
......
...@@ -25,6 +25,8 @@ qs = require "querystring" ...@@ -25,6 +25,8 @@ qs = require "querystring"
zlib = require 'zlib' zlib = require 'zlib'
axios = require 'axios' axios = require 'axios'
osu = require 'node-os-utils' osu = require 'node-os-utils'
mustache = require 'mustache'
gpt_tokenizer = require 'gpt-tokenizer/model/gpt-4o'
bunyan = require 'bunyan' bunyan = require 'bunyan'
log = global.log = bunyan.createLogger name: "mycard" log = global.log = bunyan.createLogger name: "mycard"
...@@ -511,7 +513,7 @@ loadLFList = (path) -> ...@@ -511,7 +513,7 @@ loadLFList = (path) ->
catch catch
try try
log.info("Reading YGOPro version.") log.info("Reading YGOPro version.")
cppversion = parseInt((await fs.promises.readFile(path.resolve(settings.modules.ygopro_path, 'gframe', 'game.cpp'), 'utf8')).match(/PRO_VERSION = ([x\dABCDEF]+)/)[1], '16') cppversion = parseInt((await fs.promises.readFile(path.resolve(settings.modules.ygopro_path, 'gframe', 'config.h'), 'utf8')).match(/PRO_VERSION = ([x\dABCDEF]+)/)[1], '16')
await setting_change(settings, "version", cppversion) await setting_change(settings, "version", cppversion)
log.info "ygopro version 0x"+settings.version.toString(16), "(from source code)" log.info "ygopro version 0x"+settings.version.toString(16), "(from source code)"
catch catch
...@@ -852,11 +854,11 @@ ROOM_find_or_create_by_name = global.ROOM_find_or_create_by_name = (name, player ...@@ -852,11 +854,11 @@ ROOM_find_or_create_by_name = global.ROOM_find_or_create_by_name = (name, player
uname=name.toUpperCase() uname=name.toUpperCase()
if settings.modules.windbot.enabled and (uname[0...2] == 'AI' or (!settings.modules.random_duel.enabled and uname == '')) if settings.modules.windbot.enabled and (uname[0...2] == 'AI' or (!settings.modules.random_duel.enabled and uname == ''))
return ROOM_find_or_create_ai(name) return ROOM_find_or_create_ai(name)
if settings.modules.random_duel.enabled and (uname == '' or uname == 'S' or uname == 'M' or uname == 'T' or uname == 'TOR' or uname == 'TR' or uname == 'OOR' or uname == 'OR' or uname == 'TOMR' or uname == 'TMR' or uname == 'OOMR' or uname == 'OMR' or uname == 'CR' or uname == 'CMR') if settings.modules.random_duel.enabled and (uname == '' or uname == 'S' or uname == 'M' or uname == 'T' or uname == 'TOR' or uname == 'TR' or uname == 'OOR' or uname == 'OR' or uname == 'TOMR' or uname == 'TMR' or uname == 'OOMR' or uname == 'OMR' or uname == 'CR' or uname == 'CMR' or settings.modules.random_duel.extra_modes[uname] != undefined)
return await ROOM_find_or_create_random(uname, player_ip) return await ROOM_find_or_create_random(uname, player_ip)
if room = ROOM_find_by_name(name) if room = ROOM_find_by_name(name)
return room return room
else if memory_usage >= 95 or (settings.modules.max_rooms_count and rooms_count >= settings.modules.max_rooms_count) else if memory_usage >= settings.modules.max_mem_percentage or (settings.modules.max_rooms_count and rooms_count >= settings.modules.max_rooms_count)
return null return null
else else
room = new Room(name) room = new Room(name)
...@@ -910,8 +912,9 @@ ROOM_find_or_create_random = global.ROOM_find_or_create_random = (type, player_i ...@@ -910,8 +912,9 @@ ROOM_find_or_create_random = global.ROOM_find_or_create_random = (type, player_i
else else
return null return null
if result.random_type=='S' then result.welcome2 = '${random_duel_enter_room_single}' if result.random_type=='S' then result.welcome2 = '${random_duel_enter_room_single}'
if result.random_type=='M' then result.welcome2 = '${random_duel_enter_room_match}' else if result.random_type=='M' then result.welcome2 = '${random_duel_enter_room_match}'
if result.random_type=='T' then result.welcome2 = '${random_duel_enter_room_tag}' else if result.random_type=='T' then result.welcome2 = '${random_duel_enter_room_tag}'
else result.welcome2 = settings.modules.random_duel.extra_modes[type]?.welcome ? ''
return result return result
ROOM_find_or_create_ai = global.ROOM_find_or_create_ai = (name)-> ROOM_find_or_create_ai = global.ROOM_find_or_create_ai = (name)->
...@@ -1626,6 +1629,11 @@ class Room ...@@ -1626,6 +1629,11 @@ class Room
path.resolve(settings.modules.ygopro_path, s) path.resolve(settings.modules.ygopro_path, s)
) )
.join(',') .join(',')
YGOPRO_EXTRA_SCRIPT: settings.modules.extra_script_path
.map((s) ->
path.resolve(settings.modules.ygopro_path, s)
)
.join(',')
} }
} }
) )
...@@ -1722,6 +1730,7 @@ class Room ...@@ -1722,6 +1730,7 @@ class Room
form_data.append 'start', @start_time form_data.append 'start', @start_time
form_data.append 'end', end_time form_data.append 'end', end_time
form_data.append 'arena', @arena form_data.append 'arena', @arena
form_data.append 'nonce', Math.random().toString()
post_score_process = () -> post_score_process = () ->
axios.post settings.modules.arena_mode.post_score, form_data, axios.post settings.modules.arena_mode.post_score, form_data,
...@@ -3369,7 +3378,7 @@ ygopro.stoc_send_random_tip = (client)-> ...@@ -3369,7 +3378,7 @@ ygopro.stoc_send_random_tip = (client)->
if settings.modules.tips.split_zh and tips.tips_zh.length and client.lang == "zh-cn" if settings.modules.tips.split_zh and tips.tips_zh.length and client.lang == "zh-cn"
tip_type = "tips_zh" tip_type = "tips_zh"
if settings.modules.tips.enabled && tips.tips.length && !client.is_local && !client.closed if settings.modules.tips.enabled && tips.tips.length && !client.is_local && !client.closed
ygopro.stoc_send_chat(client, "Tip: " + tips[tip_type][Math.floor(Math.random() * tips[tip_type].length)]) ygopro.stoc_send_chat(client, settings.modules.tips.prefix + tips[tip_type][Math.floor(Math.random() * tips[tip_type].length)])
await return await return
ygopro.stoc_send_random_tip_to_room = (room)-> ygopro.stoc_send_random_tip_to_room = (room)->
if settings.modules.tips.enabled && tips.tips.length if settings.modules.tips.enabled && tips.tips.length
...@@ -3708,14 +3717,30 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server, datas)-> ...@@ -3708,14 +3717,30 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server, datas)->
cancel = true cancel = true
if not cancel and settings.modules.chatgpt.enabled and room.windbot and not client.is_post_watcher and client.pos < 2 and not client.is_local if not cancel and settings.modules.chatgpt.enabled and room.windbot and not client.is_post_watcher and client.pos < 2 and not client.is_local
# session_key = "#{settings.modules.chatgpt.session}:#{settings.port}:#{CLIENT_get_authorize_key(client)}" # session_key = "#{settings.modules.chatgpt.session}:#{settings.port}:#{CLIENT_get_authorize_key(client)}"
if room.is_requesting_chatgpt
return false
room.is_requesting_chatgpt = true
if not room.chatgpt_conversation
room.chatgpt_conversation = []
openai_req_body = { openai_req_body = {
messages: [ messages: Array.from(room.chatgpt_conversation),
{ role: "user", content: msg }
],
model: settings.modules.chatgpt.model model: settings.modules.chatgpt.model
} }
openai_req_body.messages.push { role: "user", content: msg }
shrink_index = 0
if settings.modules.chatgpt.system_prompt if settings.modules.chatgpt.system_prompt
openai_req_body.messages.unshift { role: "system", content: settings.modules.chatgpt.system_prompt.replace } openai_req_body.messages.unshift { role: "system", content: mustache.render(settings.modules.chatgpt.system_prompt, {
player: client.name,
windbot: room.windbot.name,
}, undefined, { escape: (v) -> v }) }
shrink_index = 1
# trim conversation if too long
shrink_count = 0
while !gpt_tokenizer.isWithinTokenLimit(openai_req_body.messages, settings.modules.chatgpt.max_tokens)
if openai_req_body.messages.length <= (1 + shrink_index)
break
openai_req_body.messages.splice(shrink_index, 2) # remove the oldest user+assistant pair
shrink_count += 2
Object.assign(openai_req_body, settings.modules.chatgpt.extra_opts) Object.assign(openai_req_body, settings.modules.chatgpt.extra_opts)
axios.post("#{settings.modules.chatgpt.endpoint}/v1/chat/completions", openai_req_body, { axios.post("#{settings.modules.chatgpt.endpoint}/v1/chat/completions", openai_req_body, {
timeout: 300000, timeout: 300000,
...@@ -3732,8 +3757,15 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server, datas)-> ...@@ -3732,8 +3757,15 @@ ygopro.ctos_follow 'CHAT', true, (buffer, info, client, server, datas)->
ygopro.stoc_send_chat_to_room(room, chunk.join(''), 1 - client.pos) ygopro.stoc_send_chat_to_room(room, chunk.join(''), 1 - client.pos)
else else
ygopro.stoc_send_chat_to_room(room, ' ', 1 - client.pos) ygopro.stoc_send_chat_to_room(room, ' ', 1 - client.pos)
# save text
if shrink_count > 0
room.chatgpt_conversation.splice(0, shrink_count)
room.chatgpt_conversation.push { role: "user", content: msg }
room.chatgpt_conversation.push { role: "assistant", content: text }
).catch((err) -> ).catch((err) ->
log.error "CHATGPT ERROR", err log.error "CHATGPT ERROR", err
).finally(() ->
room.is_requesting_chatgpt = false
) )
return false return false
if !(room and (room.random_type or room.arena)) and not settings.modules.mycard.enabled if !(room and (room.random_type or room.arena)) and not settings.modules.mycard.enabled
...@@ -3899,14 +3931,10 @@ ygopro.ctos_follow 'UPDATE_DECK', true, (buffer, info, client, server, datas)-> ...@@ -3899,14 +3931,10 @@ ygopro.ctos_follow 'UPDATE_DECK', true, (buffer, info, client, server, datas)->
else else
log.warn("GET ATHLETIC FAIL", client.name, athleticCheckResult.message) log.warn("GET ATHLETIC FAIL", client.name, athleticCheckResult.message)
if settings.modules.tournament_mode.enabled and settings.modules.tournament_mode.deck_check if settings.modules.tournament_mode.enabled and settings.modules.tournament_mode.deck_check
client_deck_obj = YGOProDeck.fromUpdateDeckPayload(buffer)
if settings.modules.challonge.enabled and client.challonge_info and client.challonge_info.deckbuf if settings.modules.challonge.enabled and client.challonge_info and client.challonge_info.deckbuf
trim_deckbuf = (buf) -> deck_obj = YGOProDeck.fromUpdateDeckPayload(Buffer.from(client.challonge_info.deckbuf, "base64"))
mainc = buf.readUInt32LE(0) if deck_obj.isEqual(client_deck_obj, { ignoreOrder: true })
sidec = buf.readUInt32LE(4)
# take first (2 + mainc + sidec) * 4 bytes
return buf.slice(0, (2 + mainc + sidec) * 4)
deckbuf_from_challonge = Buffer.from(client.challonge_info.deckbuf, "base64")
if trim_deckbuf(deckbuf_from_challonge).equals(trim_deckbuf(buffer))
#log.info("deck ok: " + client.name) #log.info("deck ok: " + client.name)
return deck_ok("${deck_correct_part1} #{client.challonge_info.name} ${deck_correct_part2}") return deck_ok("${deck_correct_part1} #{client.challonge_info.name} ${deck_correct_part2}")
else else
...@@ -3915,16 +3943,14 @@ ygopro.ctos_follow 'UPDATE_DECK', true, (buffer, info, client, server, datas)-> ...@@ -3915,16 +3943,14 @@ ygopro.ctos_follow 'UPDATE_DECK', true, (buffer, info, client, server, datas)->
else else
decks = await fs.promises.readdir(settings.modules.tournament_mode.deck_path) decks = await fs.promises.readdir(settings.modules.tournament_mode.deck_path)
if decks.length if decks.length
found_deck=false found_deck = decks.find((deck) -> deck_name_match(deck, client.name))
for deck in decks
if deck_name_match(deck, client.name)
found_deck=deck
if found_deck if found_deck
deck_text = await fs.promises.readFile(settings.modules.tournament_mode.deck_path+found_deck,{encoding:"ASCII"}) deck_text = await fs.promises.readFile(settings.modules.tournament_mode.deck_path+found_deck,{encoding:"ASCII"})
deck_obj = YGOProDeck.fromYdkString(deck_text) deck_obj = YGOProDeck.fromYdkString(deck_text)
deck_main=deck_obj.main.concat(deck_obj.extra) # put extra cards to main
deck_side=deck_obj.side deck_obj.main = deck_obj.main.concat(deck_obj.extra)
if _.isEqual(buff_main, deck_main) and _.isEqual(buff_side, deck_side) deck_obj.extra = []
if client_deck_obj.isEqual(deck_obj, { ignoreOrder: true })
#log.info("deck ok: " + client.name) #log.info("deck ok: " + client.name)
return deck_ok("${deck_correct_part1} #{found_deck} ${deck_correct_part2}") return deck_ok("${deck_correct_part1} #{found_deck} ${deck_correct_part2}")
else else
......
This diff is collapsed.
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