Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
S
srvpro2
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Locked Files
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Security & Compliance
Security & Compliance
Dependency List
License Compliance
Packages
Packages
List
Container Registry
Analytics
Analytics
CI / CD
Code Review
Insights
Issues
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nanahira
srvpro2
Commits
638f3121
Commit
638f3121
authored
Feb 14, 2026
by
nanahira
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
agents
parent
b125821a
Pipeline
#43196
passed with stages
in 1 minute and 29 seconds
Changes
9
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
48 additions
and
5 deletions
+48
-5
AGENTS.md
AGENTS.md
+13
-0
config.example.yaml
config.example.yaml
+7
-0
src/app.ts
src/app.ts
+2
-0
src/client/client-handler.ts
src/client/client-handler.ts
+7
-0
src/config.ts
src/config.ts
+1
-0
src/feats/client-version-check.ts
src/feats/client-version-check.ts
+4
-0
src/feats/feats-module.ts
src/feats/feats-module.ts
+7
-0
src/join-handlers/join-handler-module.ts
src/join-handlers/join-handler-module.ts
+1
-1
src/room/room.ts
src/room/room.ts
+6
-4
No files found.
AGENTS.md
View file @
638f3121
...
@@ -7,11 +7,24 @@
...
@@ -7,11 +7,24 @@
-
非必要不要在 Room 和 Client 里面加字段或者方法。如果可以的话请使用定义 interface 进行依赖合并。
-
非必要不要在 Room 和 Client 里面加字段或者方法。如果可以的话请使用定义 interface 进行依赖合并。
-
进行协议设计需要核对 ygopro 和 srvpro 的 coffee 和 cpp 的实现。
-
进行协议设计需要核对 ygopro 和 srvpro 的 coffee 和 cpp 的实现。
-
尽量定义新的模块实现功能,而不是在之前的方法上进行修改。
-
尽量定义新的模块实现功能,而不是在之前的方法上进行修改。
-
配置在 config.ts 里面写默认类型。注意所有类型必须是 string 并且全部大写字母。改了之后需要 npm run gen:config-example 生成 config.example.yaml
-
如果 Room 的事件不够,可以加,然后在对应的点加 dispatch。
-
Room 的事件不要依赖 YGOProMsgStart 或者 YGOProMsgWin 这样的直接消息事件(经常会不准,这些事件只适合用来构建 replay),应该依赖 Room 专用事件。
-
定义 middleware 如果不是拦截消息,必须 return next()
## 模块结构
-
客户端收发相关:TransportModule
-
额外功能相关:FeatsModule(所有的本来 srvpro 处理的各种额外功能都放在这里。日后做的扩展都在这里)
-
房间核心相关:RoomModule(用来复刻 ygopro 功能)
-
加入相关:JoinHandlerModule(专门用来处理 YGOProCtosJoinGame 用来分配房间,比如房间或者随机对战什么的)
## 部分实现细节
## 部分实现细节
### 和 srvpro 的对应关系
### 和 srvpro 的对应关系
本项目是一个直接操作 ocgcore 的项目,而 srvpro 是依靠『把自己夹在客户端和 server 之间』来工作的。因此某些实现方式要调整。
-
srvpro 里面的 client.send(发送给客户端)还是对应 client.send
-
srvpro 里面的 client.send(发送给客户端)还是对应 client.send
-
srvpro 里面 server.send(模拟客户端发送消息)对应 this.ctx.dispatch(msgClassInstance, client)
-
srvpro 里面 server.send(模拟客户端发送消息)对应 this.ctx.dispatch(msgClassInstance, client)
...
...
config.example.yaml
View file @
638f3121
...
@@ -8,10 +8,17 @@ SSL_CERT: ""
...
@@ -8,10 +8,17 @@ SSL_CERT: ""
SSL_KEY
:
"
"
SSL_KEY
:
"
"
TRUSTED_PROXIES
:
127.0.0.0/8,::1/128
TRUSTED_PROXIES
:
127.0.0.0/8,::1/128
NO_CONNECT_COUNT_LIMIT
:
"
"
NO_CONNECT_COUNT_LIMIT
:
"
"
YGOPRO_VERSION
:
"
"
ALT_VERSIONS
:
"
"
ALT_VERSIONS
:
"
"
USE_PROXY
:
"
"
USE_PROXY
:
"
"
YGOPRO_PATH
:
./ygopro
YGOPRO_PATH
:
./ygopro
EXTRA_SCRIPT_PATH
:
"
"
EXTRA_SCRIPT_PATH
:
"
"
DECK_MAIN_MIN
:
"
40"
DECK_MAIN_MAX
:
"
60"
DECK_EXTRA_MAX
:
"
15"
DECK_SIDE_MAX
:
"
15"
DECK_MAX_COPIES
:
"
3"
OCGCORE_DEBUG_LOG
:
"
"
HOSTINFO_LFLIST
:
"
0"
HOSTINFO_LFLIST
:
"
0"
HOSTINFO_RULE
:
"
0"
HOSTINFO_RULE
:
"
0"
HOSTINFO_MODE
:
"
0"
HOSTINFO_MODE
:
"
0"
...
...
src/app.ts
View file @
638f3121
...
@@ -8,6 +8,7 @@ import { TransportModule } from './client/transport-module';
...
@@ -8,6 +8,7 @@ import { TransportModule } from './client/transport-module';
import
{
JoinHandlerModule
}
from
'
./join-handlers/join-handler-module
'
;
import
{
JoinHandlerModule
}
from
'
./join-handlers/join-handler-module
'
;
import
{
RoomModule
}
from
'
./room/room-module
'
;
import
{
RoomModule
}
from
'
./room/room-module
'
;
import
{
SqljsFactory
,
SqljsLoader
}
from
'
./services/sqljs
'
;
import
{
SqljsFactory
,
SqljsLoader
}
from
'
./services/sqljs
'
;
import
{
FeatsModule
}
from
'
./feats/feats-module
'
;
const
core
=
createAppContext
()
const
core
=
createAppContext
()
.
provide
(
ConfigService
,
{
.
provide
(
ConfigService
,
{
...
@@ -28,6 +29,7 @@ export type ContextState = AppContextState<Context>;
...
@@ -28,6 +29,7 @@ export type ContextState = AppContextState<Context>;
export
const
app
=
core
export
const
app
=
core
.
use
(
TransportModule
)
.
use
(
TransportModule
)
.
use
(
FeatsModule
)
.
use
(
RoomModule
)
.
use
(
RoomModule
)
.
use
(
JoinHandlerModule
)
.
use
(
JoinHandlerModule
)
.
define
();
.
define
();
src/client/client-handler.ts
View file @
638f3121
...
@@ -82,6 +82,13 @@ export class ClientHandler {
...
@@ -82,6 +82,13 @@ export class ClientHandler {
const
receive$
=
merge
(
client
.
receive$
,
disconnect$
);
const
receive$
=
merge
(
client
.
receive$
,
disconnect$
);
receive$
.
subscribe
(
async
(
msg
)
=>
{
receive$
.
subscribe
(
async
(
msg
)
=>
{
this
.
logger
.
debug
(
{
msgName
:
msg
.
constructor
.
name
,
client
:
client
.
name
||
client
.
loggingIp
(),
},
'
Received client message
'
,
);
try
{
try
{
await
this
.
ctx
.
dispatch
(
msg
,
client
);
await
this
.
ctx
.
dispatch
(
msg
,
client
);
}
catch
(
e
)
{
}
catch
(
e
)
{
...
...
src/config.ts
View file @
638f3121
...
@@ -18,6 +18,7 @@ export const defaultConfig = {
...
@@ -18,6 +18,7 @@ export const defaultConfig = {
SSL_KEY
:
''
,
SSL_KEY
:
''
,
TRUSTED_PROXIES
:
'
127.0.0.0/8,::1/128
'
,
TRUSTED_PROXIES
:
'
127.0.0.0/8,::1/128
'
,
NO_CONNECT_COUNT_LIMIT
:
''
,
NO_CONNECT_COUNT_LIMIT
:
''
,
YGOPRO_VERSION
:
''
,
ALT_VERSIONS
:
''
,
ALT_VERSIONS
:
''
,
USE_PROXY
:
''
,
USE_PROXY
:
''
,
YGOPRO_PATH
:
'
./ygopro
'
,
YGOPRO_PATH
:
'
./ygopro
'
,
...
...
src/
join-handler
s/client-version-check.ts
→
src/
feat
s/client-version-check.ts
View file @
638f3121
...
@@ -11,6 +11,10 @@ const YGOPRO_VERSION = 0x1362;
...
@@ -11,6 +11,10 @@ const YGOPRO_VERSION = 0x1362;
export
class
ClientVersionCheck
{
export
class
ClientVersionCheck
{
private
altVersions
=
convertNumberArray
(
this
.
ctx
.
getConfig
(
'
ALT_VERSIONS
'
));
private
altVersions
=
convertNumberArray
(
this
.
ctx
.
getConfig
(
'
ALT_VERSIONS
'
));
version
=
parseInt
(
this
.
ctx
.
getConfig
(
'
YGOPRO_VERSION
'
,
YGOPRO_VERSION
.
toString
()),
);
constructor
(
private
ctx
:
Context
)
{
constructor
(
private
ctx
:
Context
)
{
this
.
ctx
.
middleware
(
YGOProCtosJoinGame
,
async
(
msg
,
client
,
next
)
=>
{
this
.
ctx
.
middleware
(
YGOProCtosJoinGame
,
async
(
msg
,
client
,
next
)
=>
{
if
(
msg
.
version
===
YGOPRO_VERSION
)
{
if
(
msg
.
version
===
YGOPRO_VERSION
)
{
...
...
src/feats/feats-module.ts
0 → 100644
View file @
638f3121
import
{
createAppContext
}
from
'
nfkit
'
;
import
{
ClientVersionCheck
}
from
'
./client-version-check
'
;
import
{
ContextState
}
from
'
../app
'
;
export
const
FeatsModule
=
createAppContext
<
ContextState
>
()
.
provide
(
ClientVersionCheck
)
.
define
();
src/join-handlers/join-handler-module.ts
View file @
638f3121
import
{
createAppContext
}
from
'
nfkit
'
;
import
{
createAppContext
}
from
'
nfkit
'
;
import
{
ContextState
}
from
'
../app
'
;
import
{
ContextState
}
from
'
../app
'
;
import
{
ClientVersionCheck
}
from
'
./client-version-check
'
;
import
{
ClientVersionCheck
}
from
'
.
./feats
/client-version-check
'
;
import
{
JoinRoom
}
from
'
./join-room
'
;
import
{
JoinRoom
}
from
'
./join-room
'
;
import
{
JoinFallback
}
from
'
./fallback
'
;
import
{
JoinFallback
}
from
'
./fallback
'
;
...
...
src/room/room.ts
View file @
638f3121
...
@@ -168,7 +168,6 @@ export class Room {
...
@@ -168,7 +168,6 @@ export class Room {
if
(
this
.
hostinfo
.
lflist
>=
0
)
{
if
(
this
.
hostinfo
.
lflist
>=
0
)
{
this
.
lflist
=
(
await
this
.
findLFList
())
||
blankLFList
;
this
.
lflist
=
(
await
this
.
findLFList
())
||
blankLFList
;
}
}
this
.
logger
.
debug
({
winMatchCount
:
this
.
winMatchCount
},
'
Match win count
'
);
return
this
;
return
this
;
}
}
...
@@ -1284,7 +1283,10 @@ export class Room {
...
@@ -1284,7 +1283,10 @@ export class Room {
}
}
}
}
private
async
refreshSingle
(
refresh
:
RequireQueryCardLocation
)
{
private
async
refreshSingle
(
refresh
:
RequireQueryCardLocation
,
options
:
{
queryFlag
?:
number
;
sendToClient
?:
MayBeArray
<
Client
>
}
=
{},
)
{
if
(
!
this
.
ocgcore
)
{
if
(
!
this
.
ocgcore
)
{
return
;
return
;
}
}
...
@@ -1295,7 +1297,7 @@ export class Room {
...
@@ -1295,7 +1297,7 @@ export class Room {
location
,
location
,
sequence
:
refresh
.
sequence
,
sequence
:
refresh
.
sequence
,
queryFlag
:
queryFlag
:
0xf81fff
|
(
options
.
queryFlag
??
0xf81fff
)
|
OcgcoreCommonConstants
.
QUERY_CODE
|
OcgcoreCommonConstants
.
QUERY_CODE
|
OcgcoreCommonConstants
.
QUERY_POSITION
,
OcgcoreCommonConstants
.
QUERY_POSITION
,
useCache
:
0
,
useCache
:
0
,
...
@@ -1314,7 +1316,7 @@ export class Room {
...
@@ -1314,7 +1316,7 @@ export class Room {
return
empty
;
return
empty
;
})(),
})(),
}),
}),
true
,
{
sendToClient
:
options
.
sendToClient
,
route
:
true
}
,
);
);
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment