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
c33d8afa
Commit
c33d8afa
authored
Feb 14, 2026
by
nanahira
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sort some room fields
parent
0899179e
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
72 additions
and
26 deletions
+72
-26
AGENTS.md
AGENTS.md
+22
-0
src/client/index.ts
src/client/index.ts
+1
-0
src/room/index.ts
src/room/index.ts
+1
-0
src/room/room.ts
src/room/room.ts
+48
-26
No files found.
AGENTS.md
0 → 100644
View file @
c33d8afa
# 项目情况
本项目是 SRVPro(YGOPro 服务器)项目的下一代项目。
## 项目规范
-
非必要不要在 Room 和 Client 里面加字段或者方法。如果可以的话请使用定义 interface 进行依赖合并。
-
进行协议设计需要核对 ygopro 和 srvpro 的 coffee 和 cpp 的实现。
-
尽量定义新的模块实现功能,而不是在之前的方法上进行修改。
## 参考项目
可以参考电脑的下面的项目,用来参考
-
ygopro-msg-encode(js 协议库): ~/ygo/ygopro-msg-encode
-
koishipro-core.js(wasm 层): ~/ygo/koishipro-core.js
-
ocgcore(YGOPro ocgcore 内核): ~/ygo/ygopro/ocgcore
-
ygopro(YGOPro 主程序服务端): ~/ygo/ygopro/gframe
-
srvpro(本项目的上一代): ~/ygo/ygopro/srvpro-koishi
-
yuzuthread(多线程执行器): ~/test/yuzuthread
-
typed-reflector(反射器): ~/test/koishi-related/typed-reflector
-
nfkit(工具库,事件触发器,IoC): ~/test/nfkit
src/client/index.ts
0 → 100644
View file @
c33d8afa
export
*
from
'
./client
'
;
src/room/index.ts
0 → 100644
View file @
c33d8afa
export
*
from
'
./room
'
;
src/room/room.ts
View file @
c33d8afa
import
{
Awaitable
,
ProtoMiddlewareDispatcher
}
from
'
nfkit
'
;
import
{
Awaitable
,
MayBeArray
,
ProtoMiddlewareDispatcher
}
from
'
nfkit
'
;
import
{
Context
}
from
'
../app
'
;
import
{
Context
}
from
'
../app
'
;
import
BetterLock
from
'
better-lock
'
;
import
BetterLock
from
'
better-lock
'
;
import
{
import
{
...
@@ -90,6 +90,7 @@ import { isUpdateMessage } from '../utility/is-update-message';
...
@@ -90,6 +90,7 @@ import { isUpdateMessage } from '../utility/is-update-message';
import
{
getMessageIdentifier
}
from
'
../utility/get-message-identifier
'
;
import
{
getMessageIdentifier
}
from
'
../utility/get-message-identifier
'
;
import
{
canIncreaseTime
}
from
'
../utility/can-increase-time
'
;
import
{
canIncreaseTime
}
from
'
../utility/can-increase-time
'
;
import
{
TimerState
}
from
'
./timer-state
'
;
import
{
TimerState
}
from
'
./timer-state
'
;
import
{
makeArray
}
from
'
aragami/dist/src/utility/utility
'
;
const
{
OcgcoreScriptConstants
}
=
_OcgcoreConstants
;
const
{
OcgcoreScriptConstants
}
=
_OcgcoreConstants
;
...
@@ -1194,10 +1195,10 @@ export class Room {
...
@@ -1194,10 +1195,10 @@ export class Room {
this
.
phase
=
undefined
;
this
.
phase
=
undefined
;
this
.
resetDuelTimerState
();
this
.
resetDuelTimerState
();
await
this
.
handle
GameMsg
(
watcherMsg
.
msg
);
await
this
.
dispatch
GameMsg
(
watcherMsg
.
msg
);
await
this
.
ctx
.
dispatch
(
await
this
.
ctx
.
dispatch
(
new
OnRoomDuelStart
(
this
),
new
OnRoomDuelStart
(
this
),
this
.
g
et
OperatingPlayer
(
this
.
turnIngamePos
),
this
.
g
atIngame
OperatingPlayer
(
this
.
turnIngamePos
),
);
);
await
Promise
.
all
([
await
Promise
.
all
([
...
@@ -1232,7 +1233,7 @@ export class Room {
...
@@ -1232,7 +1233,7 @@ export class Room {
this
.
phase
=
phase
;
this
.
phase
=
phase
;
}
}
g
et
OperatingPlayer
(
ingameDuelPos
:
number
):
Client
|
undefined
{
g
atIngame
OperatingPlayer
(
ingameDuelPos
:
number
):
Client
|
undefined
{
const
players
=
this
.
getIngameDuelPosPlayers
(
ingameDuelPos
);
const
players
=
this
.
getIngameDuelPosPlayers
(
ingameDuelPos
);
if
(
!
this
.
isTag
)
{
if
(
!
this
.
isTag
)
{
return
players
[
0
];
return
players
[
0
];
...
@@ -1257,7 +1258,10 @@ export class Room {
...
@@ -1257,7 +1258,10 @@ export class Room {
return
players
[
0
];
return
players
[
0
];
}
}
private
async
refreshLocations
(
refresh
:
RequireQueryLocation
)
{
private
async
refreshLocations
(
refresh
:
RequireQueryLocation
,
options
:
{
queryFlag
?:
number
;
sendToClient
?:
MayBeArray
<
Client
>
}
=
{},
)
{
if
(
!
this
.
ocgcore
)
{
if
(
!
this
.
ocgcore
)
{
return
;
return
;
}
}
...
@@ -1266,16 +1270,16 @@ export class Room {
...
@@ -1266,16 +1270,16 @@ export class Room {
const
{
cards
}
=
await
this
.
ocgcore
.
queryFieldCard
({
const
{
cards
}
=
await
this
.
ocgcore
.
queryFieldCard
({
player
:
refresh
.
player
,
player
:
refresh
.
player
,
location
,
location
,
queryFlag
:
getZoneQueryFlag
(
location
),
queryFlag
:
options
.
queryFlag
??
getZoneQueryFlag
(
location
),
useCache
:
1
,
useCache
:
1
,
});
});
await
this
.
handle
GameMsg
(
await
this
.
dispatch
GameMsg
(
new
YGOProMsgUpdateData
().
fromPartial
({
new
YGOProMsgUpdateData
().
fromPartial
({
player
:
refresh
.
player
,
player
:
refresh
.
player
,
location
,
location
,
cards
:
cards
??
[],
cards
:
cards
??
[],
}),
}),
true
,
{
sendToClient
:
options
.
sendToClient
,
route
:
true
}
,
);
);
}
}
}
}
...
@@ -1296,7 +1300,7 @@ export class Room {
...
@@ -1296,7 +1300,7 @@ export class Room {
OcgcoreCommonConstants
.
QUERY_POSITION
,
OcgcoreCommonConstants
.
QUERY_POSITION
,
useCache
:
0
,
useCache
:
0
,
});
});
await
this
.
handle
GameMsg
(
await
this
.
dispatch
GameMsg
(
new
YGOProMsgUpdateCard
().
fromPartial
({
new
YGOProMsgUpdateCard
().
fromPartial
({
controller
:
refresh
.
player
,
controller
:
refresh
.
player
,
location
,
location
,
...
@@ -1325,7 +1329,7 @@ export class Room {
...
@@ -1325,7 +1329,7 @@ export class Room {
}
}
private
async
sendWaitingToNonOperator
(
ingameDuelPos
:
number
)
{
private
async
sendWaitingToNonOperator
(
ingameDuelPos
:
number
)
{
const
operatingPlayer
=
this
.
g
et
OperatingPlayer
(
ingameDuelPos
);
const
operatingPlayer
=
this
.
g
atIngame
OperatingPlayer
(
ingameDuelPos
);
const
noOps
=
this
.
playingPlayers
.
filter
((
p
)
=>
p
!==
operatingPlayer
);
const
noOps
=
this
.
playingPlayers
.
filter
((
p
)
=>
p
!==
operatingPlayer
);
await
Promise
.
all
(
await
Promise
.
all
(
noOps
.
map
((
p
)
=>
noOps
.
map
((
p
)
=>
...
@@ -1338,7 +1342,10 @@ export class Room {
...
@@ -1338,7 +1342,10 @@ export class Room {
);
);
}
}
private
async
routeGameMsg
(
message
:
YGOProMsgBase
)
{
private
async
routeGameMsg
(
message
:
YGOProMsgBase
,
options
:
{
sendToClient
?:
MayBeArray
<
Client
>
}
=
{},
)
{
if
(
!
message
)
{
if
(
!
message
)
{
return
;
return
;
}
}
...
@@ -1351,6 +1358,9 @@ export class Room {
...
@@ -1351,6 +1358,9 @@ export class Room {
const
sendTargets
=
message
.
getSendTargets
();
const
sendTargets
=
message
.
getSendTargets
();
const
sendGameMsg
=
(
c
:
Client
,
msg
:
YGOProMsgBase
)
=>
const
sendGameMsg
=
(
c
:
Client
,
msg
:
YGOProMsgBase
)
=>
c
.
send
(
new
YGOProStocGameMsg
().
fromPartial
({
msg
}));
c
.
send
(
new
YGOProStocGameMsg
().
fromPartial
({
msg
}));
const
sendToClients
=
options
.
sendToClient
?
new
Set
(
makeArray
(
options
.
sendToClient
))
:
undefined
;
await
Promise
.
all
(
await
Promise
.
all
(
sendTargets
.
map
(
async
(
pos
)
=>
{
sendTargets
.
map
(
async
(
pos
)
=>
{
if
(
pos
===
NetPlayerType
.
OBSERVER
)
{
if
(
pos
===
NetPlayerType
.
OBSERVER
)
{
...
@@ -1361,10 +1371,13 @@ export class Room {
...
@@ -1361,10 +1371,13 @@ export class Room {
}
else
{
}
else
{
const
players
=
this
.
getIngameDuelPosPlayers
(
pos
);
const
players
=
this
.
getIngameDuelPosPlayers
(
pos
);
await
Promise
.
all
(
await
Promise
.
all
(
players
.
map
((
c
)
=>
{
players
.
map
(
async
(
c
)
=>
{
if
(
sendToClients
&&
!
sendToClients
.
has
(
c
))
{
return
;
}
const
duelPos
=
this
.
getIngameDuelPos
(
c
);
const
duelPos
=
this
.
getIngameDuelPos
(
c
);
const
playerView
=
message
.
playerView
(
duelPos
);
const
playerView
=
message
.
playerView
(
duelPos
);
const
operatingPlayer
=
this
.
g
et
OperatingPlayer
(
duelPos
);
const
operatingPlayer
=
this
.
g
atIngame
OperatingPlayer
(
duelPos
);
return
sendGameMsg
(
return
sendGameMsg
(
c
,
c
,
c
===
operatingPlayer
?
playerView
:
playerView
.
teammateView
(),
c
===
operatingPlayer
?
playerView
:
playerView
.
teammateView
(),
...
@@ -1407,16 +1420,23 @@ export class Room {
...
@@ -1407,16 +1420,23 @@ export class Room {
}
}
}
}
private
async
handleGameMsg
(
message
:
YGOProMsgBase
,
route
=
false
)
{
async
dispatchGameMsg
(
const
msg1
=
await
this
.
localGameMsgDispatcher
.
dispatch
(
message
);
message
:
YGOProMsgBase
,
const
msg2
=
await
this
.
ctx
.
dispatch
(
options
:
{
sendToClient
?:
MayBeArray
<
Client
>
;
route
?:
boolean
}
=
{},
msg1
,
)
{
this
.
getOperatingPlayer
(
this
.
turnIngamePos
),
if
(
!
options
.
sendToClient
)
{
);
message
=
await
this
.
localGameMsgDispatcher
.
dispatch
(
message
);
if
(
route
)
{
message
=
await
this
.
ctx
.
dispatch
(
await
this
.
routeGameMsg
(
msg2
);
message
,
this
.
gatIngameOperatingPlayer
(
this
.
turnIngamePos
),
);
}
if
(
options
.
route
)
{
await
this
.
routeGameMsg
(
message
,
{
sendToClient
:
options
.
sendToClient
,
});
}
}
return
m
sg2
;
return
m
essage
;
}
}
localGameMsgDispatcher
=
new
ProtoMiddlewareDispatcher
({
localGameMsgDispatcher
=
new
ProtoMiddlewareDispatcher
({
...
@@ -1455,7 +1475,7 @@ export class Room {
...
@@ -1455,7 +1475,7 @@ export class Room {
})
})
.
middleware
(
YGOProMsgRetry
,
async
(
message
,
next
)
=>
{
.
middleware
(
YGOProMsgRetry
,
async
(
message
,
next
)
=>
{
if
(
this
.
responsePos
!=
null
)
{
if
(
this
.
responsePos
!=
null
)
{
const
op
=
this
.
g
et
OperatingPlayer
(
const
op
=
this
.
g
atIngame
OperatingPlayer
(
this
.
getIngameDuelPosByDuelPos
(
this
.
responsePos
),
this
.
getIngameDuelPosByDuelPos
(
this
.
responsePos
),
);
);
await
op
.
send
(
await
op
.
send
(
...
@@ -1495,7 +1515,7 @@ export class Room {
...
@@ -1495,7 +1515,7 @@ export class Room {
continue
;
continue
;
}
}
const
handled
=
await
this
.
handle
GameMsg
(
message
);
const
handled
=
await
this
.
dispatch
GameMsg
(
message
);
if
(
handled
instanceof
YGOProMsgWin
)
{
if
(
handled
instanceof
YGOProMsgWin
)
{
return
this
.
win
(
handled
);
return
this
.
win
(
handled
);
}
}
...
@@ -1524,7 +1544,9 @@ export class Room {
...
@@ -1524,7 +1544,9 @@ export class Room {
}
}
if
(
if
(
client
!==
client
!==
this
.
getOperatingPlayer
(
this
.
getIngameDuelPosByDuelPos
(
this
.
responsePos
))
this
.
gatIngameOperatingPlayer
(
this
.
getIngameDuelPosByDuelPos
(
this
.
responsePos
),
)
)
{
)
{
return
;
return
;
}
}
...
@@ -1557,7 +1579,7 @@ export class Room {
...
@@ -1557,7 +1579,7 @@ export class Room {
if
(
if
(
this
.
responsePos
==
null
||
this
.
responsePos
==
null
||
client
!==
client
!==
this
.
g
et
OperatingPlayer
(
this
.
g
atIngame
OperatingPlayer
(
this
.
getIngameDuelPosByDuelPos
(
this
.
responsePos
),
this
.
getIngameDuelPosByDuelPos
(
this
.
responsePos
),
)
||
)
||
!
this
.
ocgcore
!
this
.
ocgcore
...
...
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