Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
ziqian zhang
Grasscutter
Commits
01b190bc
Commit
01b190bc
authored
May 07, 2022
by
Magix
Committed by
GitHub
May 07, 2022
Browse files
UPGRADE TO 1.1.0 POG
Merge `development` into `stable`
parents
6b81b888
1beddf16
Changes
497
Show whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/server/event/player/PlayerQuitEvent.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.server.event.player
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.server.event.types.GameEvent
;
import
emu.grasscutter.server.event.types.PlayerEvent
;
public
final
class
PlayerQuitEvent
extends
PlayerEvent
{
public
PlayerQuitEvent
(
Player
player
)
{
super
(
player
);
}
}
src/main/java/emu/grasscutter/server/event/player/PlayerReceiveMailEvent.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.server.event.player
;
import
emu.grasscutter.game.mail.Mail
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.server.event.Cancellable
;
import
emu.grasscutter.server.event.types.PlayerEvent
;
public
final
class
PlayerReceiveMailEvent
extends
PlayerEvent
implements
Cancellable
{
private
Mail
message
;
public
PlayerReceiveMailEvent
(
Player
player
,
Mail
message
)
{
super
(
player
);
this
.
message
=
message
;
}
public
void
setMessage
(
Mail
message
)
{
this
.
message
=
message
;
}
public
Mail
getMessage
()
{
return
this
.
message
;
}
}
src/main/java/emu/grasscutter/server/event/types/GameEvent.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.server.event.types
;
import
emu.grasscutter.server.event.Event
;
/**
* An event that is related to the game.
*/
public
abstract
class
GameEvent
extends
Event
{
}
\ No newline at end of file
src/main/java/emu/grasscutter/server/event/types/PlayerEvent.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.server.event.types
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.server.event.Event
;
/**
* An event that is related to player interactions.
*/
public
abstract
class
PlayerEvent
extends
Event
{
protected
final
Player
player
;
public
PlayerEvent
(
Player
player
)
{
this
.
player
=
player
;
}
public
Player
getPlayer
()
{
return
this
.
player
;
}
}
src/main/java/emu/grasscutter/server/event/types/ServerEvent.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.server.event.types
;
import
emu.grasscutter.server.event.Event
;
/**
* An event that is related to the internals of the server.
*/
public
abstract
class
ServerEvent
extends
Event
{
protected
final
Type
type
;
public
ServerEvent
(
Type
type
)
{
this
.
type
=
type
;
}
public
Type
getServerType
()
{
return
this
.
type
;
}
public
enum
Type
{
DISPATCH
,
GAME
}
}
src/main/java/emu/grasscutter/server/game/GameServer.java
View file @
01b190bc
package
emu.grasscutter.server.game
;
import
java.net.InetSocketAddress
;
import
java.util.*
;
import
java.util.concurrent.ConcurrentHashMap
;
import
emu.grasscutter.GenshinConstants
;
import
emu.grasscutter.GameConstants
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.command.CommandMap
;
import
emu.grasscutter.database.DatabaseHelper
;
import
emu.grasscutter.game.Account
;
import
emu.grasscutter.game.GenshinPlayer
;
import
emu.grasscutter.game.combine.CombineManger
;
import
emu.grasscutter.game.drop.DropManager
;
import
emu.grasscutter.game.dungeons.DungeonManager
;
import
emu.grasscutter.game.expedition.ExpeditionManager
;
import
emu.grasscutter.game.gacha.GachaManager
;
import
emu.grasscutter.game.managers.ChatManager
;
import
emu.grasscutter.game.managers.InventoryManager
;
import
emu.grasscutter.game.managers.MultiplayerManager
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.shop.ShopManager
;
import
emu.grasscutter.game.world.World
;
import
emu.grasscutter.net.packet.PacketHandler
;
import
emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail
;
import
emu.grasscutter.netty.MihoyoKcpServer
;
import
org.greenrobot.eventbus.EventBus
;
import
emu.grasscutter.netty.KcpServer
;
import
emu.grasscutter.server.event.types.ServerEvent
;
import
emu.grasscutter.server.event.game.ServerTickEvent
;
import
emu.grasscutter.server.event.internal.ServerStartEvent
;
import
emu.grasscutter.server.event.internal.ServerStopEvent
;
import
emu.grasscutter.task.TaskMap
;
import
java.net.InetSocketAddress
;
import
java.time.OffsetDateTime
;
import
java.util.*
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.ScheduledExecutorService
;
import
java.util.concurrent.TimeUnit
;
public
final
class
GameServer
extends
MihoyoKcpServer
{
import
static
emu
.
grasscutter
.
utils
.
Language
.
translate
;
public
final
class
GameServer
extends
KcpServer
{
private
final
InetSocketAddress
address
;
private
final
GameServerPacketHandler
packetHandler
;
private
final
Map
<
Integer
,
GenshinPlayer
>
players
;
private
final
Map
<
Integer
,
Player
>
players
;
private
final
Set
<
World
>
worlds
;
private
final
ChatManager
chatManager
;
private
final
InventoryManager
inventoryManager
;
...
...
@@ -33,23 +48,28 @@ public final class GameServer extends MihoyoKcpServer {
private
final
ShopManager
shopManager
;
private
final
MultiplayerManager
multiplayerManager
;
private
final
DungeonManager
dungeonManager
;
private
final
ExpeditionManager
expeditionManager
;
private
final
CommandMap
commandMap
;
private
final
TaskMap
taskMap
;
private
final
DropManager
dropManager
;
private
final
CombineManger
combineManger
;
public
EventBus
OnGameServerStartFinish
;
public
EventBus
OnGameServerTick
;
public
EventBus
OnGameServerStop
;
public
GameServer
()
{
this
(
new
InetSocketAddress
(
Grasscutter
.
getConfig
().
getGameServerOptions
().
Ip
,
Grasscutter
.
getConfig
().
getGameServerOptions
().
Port
));
}
public
GameServer
(
InetSocketAddress
address
)
{
super
(
address
);
OnGameServerStartFinish
=
EventBus
.
builder
().
throwSubscriberException
(
true
).
logNoSubscriberMessages
(
false
).
build
();
OnGameServerTick
=
EventBus
.
builder
().
throwSubscriberException
(
true
).
logNoSubscriberMessages
(
false
).
build
();
OnGameServerStop
=
EventBus
.
builder
().
throwSubscriberException
(
true
).
logNoSubscriberMessages
(
false
).
build
();
this
.
setServerInitializer
(
new
GameServerInitializer
(
this
));
this
.
address
=
address
;
this
.
packetHandler
=
new
GameServerPacketHandler
(
PacketHandler
.
class
);
this
.
players
=
new
ConcurrentHashMap
<>();
this
.
worlds
=
Collections
.
synchronizedSet
(
new
HashSet
<>());
this
.
chatManager
=
new
ChatManager
(
this
);
this
.
inventoryManager
=
new
InventoryManager
(
this
);
...
...
@@ -58,19 +78,10 @@ public final class GameServer extends MihoyoKcpServer {
this
.
multiplayerManager
=
new
MultiplayerManager
(
this
);
this
.
dungeonManager
=
new
DungeonManager
(
this
);
this
.
commandMap
=
new
CommandMap
(
true
);
// Schedule game loop.
Timer
gameLoop
=
new
Timer
();
gameLoop
.
scheduleAtFixedRate
(
new
TimerTask
()
{
@Override
public
void
run
()
{
try
{
onTick
();
}
catch
(
Exception
e
)
{
Grasscutter
.
getLogger
().
error
(
"An error occurred during game update."
,
e
);
}
}
},
new
Date
(),
1000L
);
this
.
taskMap
=
new
TaskMap
(
true
);
this
.
dropManager
=
new
DropManager
(
this
);
this
.
expeditionManager
=
new
ExpeditionManager
(
this
);
this
.
combineManger
=
new
CombineManger
(
this
);
// Hook into shutdown event.
Runtime
.
getRuntime
().
addShutdownHook
(
new
Thread
(
this
::
onServerShutdown
));
...
...
@@ -80,10 +91,14 @@ public final class GameServer extends MihoyoKcpServer {
return
packetHandler
;
}
public
Map
<
Integer
,
Genshin
Player
>
getPlayers
()
{
public
Map
<
Integer
,
Player
>
getPlayers
()
{
return
players
;
}
public
Set
<
World
>
getWorlds
()
{
return
worlds
;
}
public
ChatManager
getChatManager
()
{
return
chatManager
;
}
...
...
@@ -104,30 +119,46 @@ public final class GameServer extends MihoyoKcpServer {
return
multiplayerManager
;
}
public
DropManager
getDropManager
()
{
return
dropManager
;
}
public
DungeonManager
getDungeonManager
()
{
return
dungeonManager
;
}
public
ExpeditionManager
getExpeditionManager
()
{
return
expeditionManager
;
}
public
CommandMap
getCommandMap
()
{
return
this
.
commandMap
;
}
public
void
registerPlayer
(
GenshinPlayer
player
)
{
public
CombineManger
getCombineManger
(){
return
this
.
combineManger
;
}
public
TaskMap
getTaskMap
()
{
return
this
.
taskMap
;
}
public
void
registerPlayer
(
Player
player
)
{
getPlayers
().
put
(
player
.
getUid
(),
player
);
}
public
Genshin
Player
getPlayerByUid
(
int
id
)
{
public
Player
getPlayerByUid
(
int
id
)
{
return
this
.
getPlayerByUid
(
id
,
false
);
}
public
Genshin
Player
getPlayerByUid
(
int
id
,
boolean
allowOfflinePlayers
)
{
public
Player
getPlayerByUid
(
int
id
,
boolean
allowOfflinePlayers
)
{
// Console check
if
(
id
==
G
enshin
Constants
.
SERVER_CONSOLE_UID
)
{
if
(
id
==
G
ame
Constants
.
SERVER_CONSOLE_UID
)
{
return
null
;
}
// Get from online players
Genshin
Player
player
=
this
.
getPlayers
().
get
(
id
);
Player
player
=
this
.
getPlayers
().
get
(
id
);
if
(!
allowOfflinePlayers
)
{
return
player
;
...
...
@@ -143,7 +174,7 @@ public final class GameServer extends MihoyoKcpServer {
public
SocialDetail
.
Builder
getSocialDetailByUid
(
int
id
)
{
// Get from online players
Genshin
Player
player
=
this
.
getPlayerByUid
(
id
,
true
);
Player
player
=
this
.
getPlayerByUid
(
id
,
true
);
if
(
player
==
null
)
{
return
null
;
...
...
@@ -153,7 +184,7 @@ public final class GameServer extends MihoyoKcpServer {
}
public
Account
getAccountByName
(
String
username
)
{
Optional
<
Genshin
Player
>
playerOpt
=
getPlayers
().
values
().
stream
().
filter
(
player
->
player
.
getAccount
().
getUsername
().
equals
(
username
)).
findFirst
();
Optional
<
Player
>
playerOpt
=
getPlayers
().
values
().
stream
().
filter
(
player
->
player
.
getAccount
().
getUsername
().
equals
(
username
)).
findFirst
();
if
(
playerOpt
.
isPresent
())
{
return
playerOpt
.
get
().
getAccount
();
}
...
...
@@ -161,28 +192,66 @@ public final class GameServer extends MihoyoKcpServer {
}
public
void
onTick
()
throws
Exception
{
for
(
GenshinPlayer
player
:
this
.
getPlayers
().
values
())
{
Iterator
<
World
>
it
=
this
.
getWorlds
().
iterator
();
while
(
it
.
hasNext
())
{
World
world
=
it
.
next
();
if
(
world
.
getPlayerCount
()
==
0
)
{
it
.
remove
();
}
world
.
onTick
();
}
for
(
Player
player
:
this
.
getPlayers
().
values
())
{
player
.
onTick
();
}
OnGameServerTick
.
post
(
new
GameServerTickEvent
());
ServerTickEvent
event
=
new
ServerTickEvent
();
event
.
call
();
}
public
void
registerWorld
(
World
world
)
{
this
.
getWorlds
().
add
(
world
);
}
public
void
deregisterWorld
(
World
world
)
{
// TODO Auto-generated method stub
}
@Override
public
void
onStartFinish
()
{
Grasscutter
.
getLogger
().
info
(
"Game Server started on port "
+
address
.
getPort
());
public
synchronized
void
start
()
{
// Schedule game loop.
Timer
gameLoop
=
new
Timer
();
gameLoop
.
scheduleAtFixedRate
(
new
TimerTask
()
{
@Override
public
void
run
()
{
try
{
onTick
();
}
catch
(
Exception
e
)
{
Grasscutter
.
getLogger
().
error
(
translate
(
"messages.game.game_update_error"
),
e
);
}
}
},
new
Date
(),
1000L
);
OnGameServerStartFinish
.
post
(
new
GameServerStartFinishEvent
());
super
.
start
();
}
@Override
public
void
onStartFinish
()
{
Grasscutter
.
getLogger
().
info
(
translate
(
"messages.status.free_software"
));
Grasscutter
.
getLogger
().
info
(
translate
(
"messages.game.port_bind"
,
Integer
.
toString
(
address
.
getPort
())));
ServerStartEvent
event
=
new
ServerStartEvent
(
ServerEvent
.
Type
.
GAME
,
OffsetDateTime
.
now
());
event
.
call
();
}
public
void
onServerShutdown
()
{
OnGame
ServerStop
.
post
(
new
GameServerStopEvent
()
);
ServerStop
Event
event
=
new
ServerStopEvent
(
ServerEvent
.
Type
.
GAME
,
OffsetDateTime
.
now
());
event
.
call
(
);
// Kick and save all players
List
<
Genshin
Player
>
list
=
new
ArrayList
<>(
this
.
getPlayers
().
size
());
List
<
Player
>
list
=
new
ArrayList
<>(
this
.
getPlayers
().
size
());
list
.
addAll
(
this
.
getPlayers
().
values
());
for
(
Genshin
Player
player
:
list
)
{
for
(
Player
player
:
list
)
{
player
.
getSession
().
close
();
}
}
...
...
src/main/java/emu/grasscutter/server/game/GameServerInitializer.java
View file @
01b190bc
package
emu.grasscutter.server.game
;
import
emu.grasscutter.netty.
Mihoyo
KcpServerInitializer
;
import
emu.grasscutter.netty.KcpServerInitializer
;
import
io.jpower.kcp.netty.UkcpChannel
;
import
io.netty.channel.ChannelPipeline
;
public
class
GameServerInitializer
extends
Mihoyo
KcpServerInitializer
{
public
class
GameServerInitializer
extends
KcpServerInitializer
{
private
GameServer
server
;
public
GameServerInitializer
(
GameServer
server
)
{
...
...
src/main/java/emu/grasscutter/server/game/GameServerPacketHandler.java
View file @
01b190bc
...
...
@@ -2,9 +2,11 @@ package emu.grasscutter.server.game;
import
java.util.Set
;
import
emu.grasscutter.server.event.game.ReceivePacketEvent
;
import
org.reflections.Reflections
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.Grasscutter.ServerDebugMode
;
import
emu.grasscutter.net.packet.Opcodes
;
import
emu.grasscutter.net.packet.PacketHandler
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
...
...
@@ -12,6 +14,7 @@ import emu.grasscutter.server.game.GameSession.SessionState;
import
it.unimi.dsi.fastutil.ints.Int2ObjectMap
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
;
@SuppressWarnings
(
"unchecked"
)
public
class
GameServerPacketHandler
{
private
final
Int2ObjectMap
<
PacketHandler
>
handlers
;
...
...
@@ -21,21 +24,15 @@ public class GameServerPacketHandler {
this
.
registerHandlers
(
handlerClass
);
}
public
void
registerHandlers
(
Class
<?
extends
PacketHandler
>
handlerClass
)
{
Reflections
reflections
=
new
Reflections
(
"emu.grasscutter.server.packet"
);
Set
<?>
handlerClasses
=
reflections
.
getSubTypesOf
(
handlerClass
);
for
(
Object
obj
:
handlerClasses
)
{
Class
<?>
c
=
(
Class
<?>)
obj
;
public
void
registerPacketHandler
(
Class
<?
extends
PacketHandler
>
handlerClass
)
{
try
{
Opcodes
opcode
=
c
.
getAnnotation
(
Opcodes
.
class
);
Opcodes
opcode
=
handlerClass
.
getAnnotation
(
Opcodes
.
class
);
if
(
opcode
==
null
||
opcode
.
disabled
()
||
opcode
.
value
()
<=
0
)
{
continue
;
return
;
}
PacketHandler
packetHandler
=
(
PacketHandler
)
c
.
newInstance
();
PacketHandler
packetHandler
=
(
PacketHandler
)
handlerClass
.
newInstance
();
this
.
handlers
.
put
(
opcode
.
value
(),
packetHandler
);
}
catch
(
Exception
e
)
{
...
...
@@ -43,14 +40,20 @@ public class GameServerPacketHandler {
}
}
public
void
registerHandlers
(
Class
<?
extends
PacketHandler
>
handlerClass
)
{
Reflections
reflections
=
new
Reflections
(
"emu.grasscutter.server.packet"
);
Set
<?>
handlerClasses
=
reflections
.
getSubTypesOf
(
handlerClass
);
for
(
Object
obj
:
handlerClasses
)
{
this
.
registerPacketHandler
((
Class
<?
extends
PacketHandler
>)
obj
);
}
// Debug
Grasscutter
.
getLogger
().
info
(
"Registered "
+
this
.
handlers
.
size
()
+
" "
+
handlerClass
.
getSimpleName
()
+
"s"
);
}
public
void
handle
(
GameSession
session
,
int
opcode
,
byte
[]
header
,
byte
[]
payload
)
{
PacketHandler
handler
=
null
;
handler
=
this
.
handlers
.
get
(
opcode
);
PacketHandler
handler
=
this
.
handlers
.
get
(
opcode
);
if
(
handler
!=
null
)
{
try
{
...
...
@@ -77,8 +80,10 @@ public class GameServerPacketHandler {
}
}
// Handle
handler
.
handle
(
session
,
header
,
payload
);
// Invoke event.
ReceivePacketEvent
event
=
new
ReceivePacketEvent
(
session
,
opcode
,
payload
);
event
.
call
();
if
(!
event
.
isCanceled
())
// If event is not canceled, continue.
handler
.
handle
(
session
,
header
,
event
.
getPacketData
());
}
catch
(
Exception
ex
)
{
// TODO Remove this when no more needed
ex
.
printStackTrace
();
...
...
@@ -87,8 +92,8 @@ public class GameServerPacketHandler {
}
// Log unhandled packets
if
(
Grasscutter
.
getConfig
().
getGameServerOptions
().
LOG_PACKETS
)
{
//
Grasscutter.getLogger().info("Unhandled packet (" + opcode + "): " + PacketOpcodesUtil.getOpcodeName(opcode));
if
(
Grasscutter
.
getConfig
().
DebugMode
==
ServerDebugMode
.
MISSING
)
{
Grasscutter
.
getLogger
().
info
(
"Unhandled packet ("
+
opcode
+
"): "
+
emu
.
grasscutter
.
net
.
packet
.
PacketOpcodesUtil
.
getOpcodeName
(
opcode
));
}
}
}
src/main/java/emu/grasscutter/server/game/GameSession.java
View file @
01b190bc
...
...
@@ -3,13 +3,18 @@ package emu.grasscutter.server.game;
import
java.io.File
;
import
java.net.InetSocketAddress
;
import
java.nio.ByteBuffer
;
import
java.util.HashSet
;
import
java.util.Set
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.Grasscutter.ServerDebugMode
;
import
emu.grasscutter.game.Account
;
import
emu.grasscutter.game.GenshinPlayer
;
import
emu.grasscutter.net.packet.GenshinPacket
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.net.packet.BasePacket
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.packet.PacketOpcodesUtil
;
import
emu.grasscutter.netty.MihoyoKcpChannel
;
import
emu.grasscutter.netty.KcpChannel
;
import
emu.grasscutter.server.event.game.SendPacketEvent
;
import
emu.grasscutter.utils.Crypto
;
import
emu.grasscutter.utils.FileUtils
;
import
emu.grasscutter.utils.Utils
;
...
...
@@ -17,11 +22,13 @@ import io.netty.buffer.ByteBuf;
import
io.netty.buffer.Unpooled
;
import
io.netty.channel.ChannelHandlerContext
;
public
class
GameSession
extends
MihoyoKcpChannel
{
import
static
emu
.
grasscutter
.
utils
.
Language
.
translate
;
public
class
GameSession
extends
KcpChannel
{
private
GameServer
server
;
private
Account
account
;
private
Genshin
Player
player
;
private
Player
player
;
private
boolean
useSecretKey
;
private
SessionState
state
;
...
...
@@ -63,11 +70,11 @@ public class GameSession extends MihoyoKcpChannel {
return
this
.
getAccount
().
getId
();
}
public
Genshin
Player
getPlayer
()
{
public
Player
getPlayer
()
{
return
player
;
}
public
synchronized
void
setPlayer
(
Genshin
Player
player
)
{
public
synchronized
void
setPlayer
(
Player
player
)
{
this
.
player
=
player
;
this
.
player
.
setSession
(
this
);
this
.
player
.
setAccount
(
this
.
getAccount
());
...
...
@@ -108,21 +115,21 @@ public class GameSession extends MihoyoKcpChannel {
@Override
protected
void
onConnect
()
{
Grasscutter
.
getLogger
().
info
(
"Client connected from "
+
getAddress
().
getHostString
().
toLowerCase
());
Grasscutter
.
getLogger
().
info
(
translate
(
"messages.game.connect"
,
this
.
getAddress
().
getHostString
().
toLowerCase
())
)
;
}
@Override
protected
synchronized
void
onDisconnect
()
{
// Synchronize so we dont add character at the same time
Grasscutter
.
getLogger
().
info
(
"Client disconnected from "
+
getAddress
().
getHostString
().
toLowerCase
());
protected
synchronized
void
onDisconnect
()
{
// Synchronize so we don
'
t add character at the same time
.
Grasscutter
.
getLogger
().
info
(
translate
(
"messages.game.disconnect"
,
this
.
getAddress
().
getHostString
().
toLowerCase
())
)
;
// Set state so no more packets can be handled
this
.
setState
(
SessionState
.
INACTIVE
);
// Save after disconnecting
if
(
this
.
isLoggedIn
())
{
//
Save
//
Call logout event.
getPlayer
().
onLogout
();
// Remove from
game
server
// Remove from server
.
getServer
().
getPlayers
().
remove
(
getPlayer
().
getUid
());
}
}
...
...
@@ -140,47 +147,54 @@ public class GameSession extends MihoyoKcpChannel {
byte
[]
packet
=
FileUtils
.
read
(
p
);
GenshinPacket
genshinPacket
=
new
GenshinPacket
(
opcode
);
genshinPacket
.
setData
(
packet
);
// Log
logPacket
(
genshinPacket
.
getOpcode
());
BasePacket
basePacket
=
new
BasePacket
(
opcode
);
basePacket
.
setData
(
packet
);
send
(
genshin
Packet
);
send
(
base
Packet
);
}
public
void
send
(
GenshinPacket
genshinP
acket
)
{
public
void
send
(
BasePacket
p
acket
)
{
// Test
if
(
genshinP
acket
.
getOpcode
()
<=
0
)
{
if
(
p
acket
.
getOpcode
()
<=
0
)
{
Grasscutter
.
getLogger
().
warn
(
"Tried to send packet with missing cmd id!"
);
return
;
}
// Header
if
(
genshinPacket
.
shouldBuildHeader
())
{
genshinPacket
.
buildHeader
(
this
.
getNextClientSequence
());
// DO NOT REMOVE (unless we find a way to validate code before sending to client which I don't think we can)
// Stop WindSeedClientNotify from being sent for security purposes.
if
(
PacketOpcodes
.
BANNED_PACKETS
.
contains
(
packet
.
getOpcode
()))
{
return
;
}
// Build packet
byte
[]
data
=
genshinPacket
.
build
();
// Header
if
(
packet
.
shouldBuildHeader
())
{
packet
.
buildHeader
(
this
.
getNextClientSequence
());
}
// Log
if
(
Grasscutter
.
getConfig
().
getGameServerOptions
().
LOG_PACKETS
)
{
logPacket
(
genshinP
acket
);
if
(
Grasscutter
.
getConfig
().
DebugMode
==
ServerDebugMode
.
ALL
)
{
logPacket
(
p
acket
);
}
// Send
send
(
data
);
// Invoke event.
SendPacketEvent
event
=
new
SendPacketEvent
(
this
,
packet
);
event
.
call
();
if
(!
event
.
isCanceled
())
// If event is not cancelled, continue.
this
.
send
(
event
.
getPacket
().
build
());
}
private
void
logPacket
(
int
opcode
)
{
//Grasscutter.getLogger().info("SEND: " + PacketOpcodesUtil.getOpcodeName(opcode));
//System.out.println(Utils.bytesToHex(genshinPacket.getData()));
}
private
static
final
Set
<
Integer
>
loopPacket
=
Set
.
of
(
PacketOpcodes
.
PingReq
,
PacketOpcodes
.
PingRsp
,
PacketOpcodes
.
WorldPlayerRTTNotify
,
PacketOpcodes
.
UnionCmdNotify
,
PacketOpcodes
.
QueryPathReq
);
private
void
logPacket
(
GenshinPacket
genshinPacket
)
{
Grasscutter
.
getLogger
().
info
(
"SEND: "
+
PacketOpcodesUtil
.
getOpcodeName
(
genshinPacket
.
getOpcode
())
+
" ("
+
genshinPacket
.
getOpcode
()
+
")"
);
System
.
out
.
println
(
Utils
.
bytesToHex
(
genshinPacket
.
getData
()));
private
void
logPacket
(
BasePacket
packet
)
{
if
(!
loopPacket
.
contains
(
packet
.
getOpcode
()))
{
Grasscutter
.
getLogger
().
info
(
"SEND: "
+
PacketOpcodesUtil
.
getOpcodeName
(
packet
.
getOpcode
())
+
" ("
+
packet
.
getOpcode
()
+
")"
);
System
.
out
.
println
(
Utils
.
bytesToHex
(
packet
.
getData
()));
}
}
@Override
...
...
@@ -225,10 +239,12 @@ public class GameSession extends MihoyoKcpChannel {
}
// Log packet
if
(
Grasscutter
.
getConfig
().
getGameServerOptions
().
LOG_PACKETS
)
{
if
(
Grasscutter
.
getConfig
().
DebugMode
==
ServerDebugMode
.
ALL
)
{
if
(!
loopPacket
.
contains
(
opcode
))
{
Grasscutter
.
getLogger
().
info
(
"RECV: "
+
PacketOpcodesUtil
.
getOpcodeName
(
opcode
)
+
" ("
+
opcode
+
")"
);
System
.
out
.
println
(
Utils
.
bytesToHex
(
payload
));
}
}
// Handle
getServer
().
getPacketHandler
().
handle
(
this
,
opcode
,
header
,
payload
);
...
...
src/main/java/emu/grasscutter/server/packet/recv/HandlerAvatarExpeditionAllDataReq.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.server.packet.recv
;
import
emu.grasscutter.net.packet.Opcodes
;
import
emu.grasscutter.net.packet.PacketHandler
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.PacketAvatarExpeditionAllDataRsp
;
@Opcodes
(
PacketOpcodes
.
AvatarExpeditionAllDataReq
)
public
class
HandlerAvatarExpeditionAllDataReq
extends
PacketHandler
{
@Override
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
session
.
send
(
new
PacketAvatarExpeditionAllDataRsp
(
session
.
getPlayer
()));
}
}
src/main/java/emu/grasscutter/server/packet/recv/HandlerAvatarExpeditionCallBackReq.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.server.packet.recv
;
import
emu.grasscutter.net.packet.Opcodes
;
import
emu.grasscutter.net.packet.PacketHandler
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.AvatarExpeditionCallBackReqOuterClass.AvatarExpeditionCallBackReq
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.PacketAvatarExpeditionCallBackRsp
;
import
emu.grasscutter.server.packet.send.PacketAvatarExpeditionStartRsp
;
import
emu.grasscutter.utils.Utils
;
@Opcodes
(
PacketOpcodes
.
AvatarExpeditionCallBackReq
)
public
class
HandlerAvatarExpeditionCallBackReq
extends
PacketHandler
{
@Override
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
AvatarExpeditionCallBackReq
req
=
AvatarExpeditionCallBackReq
.
parseFrom
(
payload
);
for
(
int
i
=
0
;
i
<
req
.
getAvatarGuidCount
();
i
++)
{
session
.
getPlayer
().
removeExpeditionInfo
(
req
.
getAvatarGuid
(
i
));
}
session
.
getPlayer
().
save
();
session
.
send
(
new
PacketAvatarExpeditionCallBackRsp
(
session
.
getPlayer
()));
}
}
src/main/java/emu/grasscutter/server/packet/recv/HandlerAvatarExpeditionGetRewardReq.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.server.packet.recv
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.game.drop.DropData
;
import
emu.grasscutter.game.expedition.ExpeditionInfo
;
import
emu.grasscutter.game.expedition.ExpeditionRewardData
;
import
emu.grasscutter.game.expedition.ExpeditionRewardDataList
;
import
emu.grasscutter.game.inventory.GameItem
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.props.ActionReason
;
import
emu.grasscutter.net.packet.Opcodes
;
import
emu.grasscutter.net.packet.PacketHandler
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.AvatarExpeditionGetRewardReqOuterClass.AvatarExpeditionGetRewardReq
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.PacketAvatarExpeditionCallBackRsp
;
import
emu.grasscutter.server.packet.send.PacketAvatarExpeditionGetRewardRsp
;
import
emu.grasscutter.server.packet.send.PacketGadgetInteractRsp
;
import
emu.grasscutter.server.packet.send.PacketItemAddHintNotify
;
import
emu.grasscutter.utils.Utils
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.LinkedList
;
import
java.util.List
;
@Opcodes
(
PacketOpcodes
.
AvatarExpeditionGetRewardReq
)
public
class
HandlerAvatarExpeditionGetRewardReq
extends
PacketHandler
{
@Override
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
AvatarExpeditionGetRewardReq
req
=
AvatarExpeditionGetRewardReq
.
parseFrom
(
payload
);
ExpeditionInfo
expInfo
=
session
.
getPlayer
().
getExpeditionInfo
(
req
.
getAvatarGuid
());
List
<
GameItem
>
items
=
new
LinkedList
<>();
if
(
session
.
getServer
().
getExpeditionManager
().
getExpeditionRewardDataList
().
containsKey
(
expInfo
.
getExpId
()))
{
for
(
ExpeditionRewardDataList
RewardDataList
:
session
.
getServer
().
getExpeditionManager
().
getExpeditionRewardDataList
().
get
(
expInfo
.
getExpId
()))
{
if
(
RewardDataList
.
getHourTime
()
==
expInfo
.
getHourTime
()){
if
(!
RewardDataList
.
getExpeditionRewardData
().
isEmpty
()){
for
(
ExpeditionRewardData
RewardData
:
RewardDataList
.
getExpeditionRewardData
())
{
int
num
=
RewardData
.
getMinCount
();
if
(
RewardData
.
getMinCount
()
!=
RewardData
.
getMaxCount
()){
num
=
Utils
.
randomRange
(
RewardData
.
getMinCount
(),
RewardData
.
getMaxCount
());
}
items
.
add
(
new
GameItem
(
RewardData
.
getItemId
(),
num
));
}
}
}
}
}
session
.
getPlayer
().
getInventory
().
addItems
(
items
);
session
.
getPlayer
().
sendPacket
(
new
PacketItemAddHintNotify
(
items
,
ActionReason
.
ExpeditionReward
));
session
.
getPlayer
().
removeExpeditionInfo
(
req
.
getAvatarGuid
());
session
.
getPlayer
().
save
();
session
.
send
(
new
PacketAvatarExpeditionGetRewardRsp
(
session
.
getPlayer
(),
items
));
}
}
src/main/java/emu/grasscutter/server/packet/recv/HandlerAvatarExpeditionStartReq.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.server.packet.recv
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.net.packet.Opcodes
;
import
emu.grasscutter.net.packet.PacketHandler
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.AvatarExpeditionStartReqOuterClass.AvatarExpeditionStartReq
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.PacketAvatarExpeditionStartRsp
;
import
emu.grasscutter.utils.Utils
;
@Opcodes
(
PacketOpcodes
.
AvatarExpeditionStartReq
)
public
class
HandlerAvatarExpeditionStartReq
extends
PacketHandler
{
@Override
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
AvatarExpeditionStartReq
req
=
AvatarExpeditionStartReq
.
parseFrom
(
payload
);
int
startTime
=
Utils
.
getCurrentSeconds
();
session
.
getPlayer
().
addExpeditionInfo
(
req
.
getAvatarGuid
(),
req
.
getExpId
(),
req
.
getHourTime
(),
startTime
);
session
.
getPlayer
().
save
();
session
.
send
(
new
PacketAvatarExpeditionStartRsp
(
session
.
getPlayer
()));
}
}
src/main/java/emu/grasscutter/server/packet/recv/HandlerAvatarFetterLevelRewardReq.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.server.packet.recv
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.def.RewardData
;
import
emu.grasscutter.game.avatar.Avatar
;
import
emu.grasscutter.game.inventory.GameItem
;
import
emu.grasscutter.game.props.ActionReason
;
import
emu.grasscutter.net.packet.Opcodes
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.AvatarFetterLevelRewardReqOuterClass.AvatarFetterLevelRewardReq
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.PacketAvatarDataNotify
;
import
emu.grasscutter.server.packet.send.PacketAvatarFetterDataNotify
;
import
emu.grasscutter.server.packet.send.PacketAvatarFetterLevelRewardRsp
;
import
emu.grasscutter.server.packet.send.PacketItemAddHintNotify
;
import
emu.grasscutter.server.packet.send.PacketUnlockNameCardNotify
;
import
emu.grasscutter.net.packet.PacketHandler
;
@Opcodes
(
PacketOpcodes
.
AvatarFetterLevelRewardReq
)
public
class
HandlerAvatarFetterLevelRewardReq
extends
PacketHandler
{
@Override
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
AvatarFetterLevelRewardReq
req
=
AvatarFetterLevelRewardReq
.
parseFrom
(
payload
);
if
(
req
.
getFetterLevel
()
<
10
)
{
// You don't have a full level of fetter level, why do you want to get a divorce certificate?
session
.
send
(
new
PacketAvatarFetterLevelRewardRsp
(
req
.
getAvatarGuid
(),
req
.
getFetterLevel
()));
}
else
{
long
avatarGuid
=
req
.
getAvatarGuid
();
Avatar
avatar
=
session
.
getPlayer
()
.
getAvatars
()
.
getAvatarByGuid
(
avatarGuid
);
int
rewardId
=
avatar
.
getNameCardRewardId
();
RewardData
card
=
GameData
.
getRewardDataMap
().
get
(
rewardId
);
int
cardId
=
card
.
getRewardItemList
().
get
(
0
).
getItemId
();
if
(
session
.
getPlayer
().
getNameCardList
().
contains
(
cardId
))
{
// Already got divorce certificate.
session
.
getPlayer
().
sendPacket
(
new
PacketAvatarFetterLevelRewardRsp
(
req
.
getAvatarGuid
(),
req
.
getFetterLevel
(),
rewardId
));
return
;
}
GameItem
item
=
new
GameItem
(
cardId
);
session
.
getPlayer
().
getInventory
().
addItem
(
item
,
ActionReason
.
FetterLevelReward
);
session
.
getPlayer
().
sendPacket
(
new
PacketUnlockNameCardNotify
(
cardId
));
session
.
send
(
new
PacketAvatarFetterDataNotify
(
avatar
));
session
.
send
(
new
PacketAvatarDataNotify
(
avatar
.
getPlayer
()));
session
.
send
(
new
PacketAvatarFetterLevelRewardRsp
(
avatarGuid
,
req
.
getFetterLevel
(),
rewardId
));
}
}
}
src/main/java/emu/grasscutter/server/packet/recv/HandlerBuyGoodsReq.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.server.packet.recv
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.common.ItemParamData
;
import
emu.grasscutter.game.inventory.GameItem
;
import
emu.grasscutter.game.props.ActionReason
;
import
emu.grasscutter.game.shop.ShopInfo
;
import
emu.grasscutter.game.shop.ShopLimit
;
import
emu.grasscutter.game.shop.ShopManager
;
import
emu.grasscutter.net.packet.Opcodes
;
import
emu.grasscutter.net.packet.PacketHandler
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.BuyGoodsReqOuterClass
;
import
emu.grasscutter.net.proto.ItemParamOuterClass
;
import
emu.grasscutter.net.proto.ShopGoodsOuterClass
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.PacketBuyGoodsRsp
;
import
emu.grasscutter.server.packet.send.PacketStoreItemChangeNotify
;
import
emu.grasscutter.utils.Utils
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Optional
;
@Opcodes
(
PacketOpcodes
.
BuyGoodsReq
)
public
class
HandlerBuyGoodsReq
extends
PacketHandler
{
@Override
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
BuyGoodsReqOuterClass
.
BuyGoodsReq
buyGoodsReq
=
BuyGoodsReqOuterClass
.
BuyGoodsReq
.
parseFrom
(
payload
);
List
<
ShopInfo
>
configShop
=
session
.
getServer
().
getShopManager
().
getShopData
().
get
(
buyGoodsReq
.
getShopType
());
if
(
configShop
==
null
)
return
;
// Don't trust your users' input
List
<
Integer
>
targetShopGoodsId
=
buyGoodsReq
.
getGoodsListList
().
stream
().
map
(
ShopGoodsOuterClass
.
ShopGoods
::
getGoodsId
).
toList
();
for
(
int
goodsId
:
targetShopGoodsId
)
{
Optional
<
ShopInfo
>
sg2
=
configShop
.
stream
().
filter
(
x
->
x
.
getGoodsId
()
==
goodsId
).
findFirst
();
if
(
sg2
.
isEmpty
())
continue
;
ShopInfo
sg
=
sg2
.
get
();
int
currentTs
=
Utils
.
getCurrentSeconds
();
ShopLimit
shopLimit
=
session
.
getPlayer
().
getGoodsLimit
(
sg
.
getGoodsId
());
int
bought
=
0
;
if
(
shopLimit
!=
null
)
{
if
(
currentTs
>
shopLimit
.
getNextRefreshTime
())
{
shopLimit
.
setNextRefreshTime
(
ShopManager
.
getShopNextRefreshTime
(
sg
));
}
else
{
bought
=
shopLimit
.
getHasBoughtInPeriod
();
}
session
.
getPlayer
().
save
();
}
if
((
bought
+
buyGoodsReq
.
getBoughtNum
()
>
sg
.
getBuyLimit
())
&&
sg
.
getBuyLimit
()
!=
0
)
{
return
;
}
if
(
sg
.
getScoin
()
>
0
&&
session
.
getPlayer
().
getMora
()
<
buyGoodsReq
.
getBoughtNum
()
*
sg
.
getScoin
())
{
return
;
}
if
(
sg
.
getHcoin
()
>
0
&&
session
.
getPlayer
().
getPrimogems
()
<
buyGoodsReq
.
getBoughtNum
()
*
sg
.
getHcoin
())
{
return
;
}
if
(
sg
.
getMcoin
()
>
0
&&
session
.
getPlayer
().
getCrystals
()
<
buyGoodsReq
.
getBoughtNum
()
*
sg
.
getMcoin
())
{
return
;
}
HashMap
<
GameItem
,
Integer
>
itemsCache
=
new
HashMap
<>();
if
(
sg
.
getCostItemList
()
!=
null
)
{
for
(
ItemParamData
p
:
sg
.
getCostItemList
())
{
Optional
<
GameItem
>
invItem
=
session
.
getPlayer
().
getInventory
().
getItems
().
values
().
stream
().
filter
(
x
->
x
.
getItemId
()
==
p
.
getId
()).
findFirst
();
if
(
invItem
.
isEmpty
()
||
invItem
.
get
().
getCount
()
<
p
.
getCount
())
return
;
itemsCache
.
put
(
invItem
.
get
(),
p
.
getCount
()
*
buyGoodsReq
.
getBoughtNum
());
}
}
session
.
getPlayer
().
setMora
(
session
.
getPlayer
().
getMora
()
-
buyGoodsReq
.
getBoughtNum
()
*
sg
.
getScoin
());
session
.
getPlayer
().
setPrimogems
(
session
.
getPlayer
().
getPrimogems
()
-
buyGoodsReq
.
getBoughtNum
()
*
sg
.
getHcoin
());
session
.
getPlayer
().
setCrystals
(
session
.
getPlayer
().
getCrystals
()
-
buyGoodsReq
.
getBoughtNum
()
*
sg
.
getMcoin
());
if
(!
itemsCache
.
isEmpty
())
{
for
(
GameItem
gi
:
itemsCache
.
keySet
())
{
session
.
getPlayer
().
getInventory
().
removeItem
(
gi
,
itemsCache
.
get
(
gi
));
}
itemsCache
.
clear
();
}
session
.
getPlayer
().
addShopLimit
(
sg
.
getGoodsId
(),
buyGoodsReq
.
getBoughtNum
(),
ShopManager
.
getShopNextRefreshTime
(
sg
));
GameItem
item
=
new
GameItem
(
GameData
.
getItemDataMap
().
get
(
sg
.
getGoodsItem
().
getId
()));
item
.
setCount
(
buyGoodsReq
.
getBoughtNum
()
*
sg
.
getGoodsItem
().
getCount
());
session
.
getPlayer
().
getInventory
().
addItem
(
item
,
ActionReason
.
Shop
,
true
);
// fix: not notify when got virtual item from shop
session
.
send
(
new
PacketBuyGoodsRsp
(
buyGoodsReq
.
getShopType
(),
session
.
getPlayer
().
getGoodsLimit
(
sg
.
getGoodsId
()).
getHasBoughtInPeriod
(),
buyGoodsReq
.
getGoodsListList
().
stream
().
filter
(
x
->
x
.
getGoodsId
()
==
goodsId
).
findFirst
().
get
()));
}
session
.
getPlayer
().
save
();
}
}
src/main/java/emu/grasscutter/server/packet/recv/HandlerChangeMailStarNotify.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.server.packet.recv
;
import
emu.grasscutter.game.mail.Mail
;
import
emu.grasscutter.net.packet.Opcodes
;
import
emu.grasscutter.net.packet.PacketHandler
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.ChangeMailStarNotifyOuterClass
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.PacketMailChangeNotify
;
import
java.util.ArrayList
;
import
java.util.List
;
@Opcodes
(
PacketOpcodes
.
ChangeMailStarNotify
)
public
class
HandlerChangeMailStarNotify
extends
PacketHandler
{
@Override
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
ChangeMailStarNotifyOuterClass
.
ChangeMailStarNotify
req
=
ChangeMailStarNotifyOuterClass
.
ChangeMailStarNotify
.
parseFrom
(
payload
);
List
<
Mail
>
updatedMail
=
new
ArrayList
<>();
for
(
int
mailId
:
req
.
getMailIdListList
())
{
Mail
message
=
session
.
getPlayer
().
getMail
(
mailId
);
message
.
importance
=
req
.
getIsStar
()
==
true
?
1
:
0
;
session
.
getPlayer
().
replaceMailByIndex
(
mailId
,
message
);
updatedMail
.
add
(
message
);
}
session
.
send
(
new
PacketMailChangeNotify
(
session
.
getPlayer
(),
updatedMail
));
}
}
src/main/java/emu/grasscutter/server/packet/recv/HandlerCombatInvocationsNotify.java
View file @
01b190bc
package
emu.grasscutter.server.packet.recv
;
import
emu.grasscutter.game.entity.G
enshin
Entity
;
import
emu.grasscutter.game.entity.G
ame
Entity
;
import
emu.grasscutter.net.packet.Opcodes
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.CombatInvocationsNotifyOuterClass.CombatInvocationsNotify
;
...
...
@@ -16,24 +16,19 @@ public class HandlerCombatInvocationsNotify extends PacketHandler {
@Override
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
CombatInvocationsNotify
notif
=
CombatInvocationsNotify
.
parseFrom
(
payload
);
for
(
CombatInvokeEntry
entry
:
notif
.
getInvokeListList
())
{
switch
(
entry
.
getArgumentType
())
{
case
C
ombatEvtBeingHit
:
case
C
OMBAT_EVT_BEING_HIT
:
// Handle damage
EvtBeingHitInfo
hitInfo
=
EvtBeingHitInfo
.
parseFrom
(
entry
.
getCombatData
());
session
.
getPlayer
().
get
Scene
().
handleAttack
(
hitInfo
.
getAttackResult
());
session
.
getPlayer
().
get
AttackResults
().
add
(
hitInfo
.
getAttackResult
());
break
;
case
E
ntityMove
:
case
E
NTITY_MOVE
:
// Handle movement
EntityMoveInfo
moveInfo
=
EntityMoveInfo
.
parseFrom
(
entry
.
getCombatData
());
G
enshin
Entity
entity
=
session
.
getPlayer
().
getScene
().
getEntityById
(
moveInfo
.
getEntityId
());
G
ame
Entity
entity
=
session
.
getPlayer
().
getScene
().
getEntityById
(
moveInfo
.
getEntityId
());
if
(
entity
!=
null
)
{
entity
.
getPosition
().
set
(
moveInfo
.
getMotionInfo
().
getPos
());
entity
.
getRotation
().
set
(
moveInfo
.
getMotionInfo
().
getRot
());
entity
.
setLastMoveSceneTimeMs
(
moveInfo
.
getSceneTime
());
entity
.
setLastMoveReliableSeq
(
moveInfo
.
getReliableSeq
());
entity
.
setMotionState
(
moveInfo
.
getMotionInfo
().
getState
());
session
.
getPlayer
().
getMovementManager
().
handle
(
session
,
moveInfo
,
entity
);
}
break
;
default
:
...
...
@@ -46,6 +41,11 @@ public class HandlerCombatInvocationsNotify extends PacketHandler {
if
(
notif
.
getInvokeListList
().
size
()
>
0
)
{
session
.
getPlayer
().
getCombatInvokeHandler
().
update
(
session
.
getPlayer
());
}
// Handle attack results last
while
(!
session
.
getPlayer
().
getAttackResults
().
isEmpty
())
{
session
.
getPlayer
().
getScene
().
handleAttack
(
session
.
getPlayer
().
getAttackResults
().
poll
());
}
}
}
src/main/java/emu/grasscutter/server/packet/recv/HandlerCombineReq.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.server.packet.recv
;
import
emu.grasscutter.data.def.CombineData
;
import
emu.grasscutter.net.packet.Opcodes
;
import
emu.grasscutter.net.packet.PacketHandler
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.CombineReqOuterClass
;
import
emu.grasscutter.net.proto.ItemParamOuterClass
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.PacketCombineRsp
;
import
java.util.List
;
import
java.util.stream.Collectors
;
@Opcodes
(
PacketOpcodes
.
CombineReq
)
public
class
HandlerCombineReq
extends
PacketHandler
{
@Override
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
CombineReqOuterClass
.
CombineReq
req
=
CombineReqOuterClass
.
CombineReq
.
parseFrom
(
payload
);
var
result
=
session
.
getServer
().
getCombineManger
()
.
combineItem
(
session
.
getPlayer
(),
req
.
getCombineId
(),
req
.
getCombineCount
());
if
(
result
==
null
){
return
;
}
session
.
send
(
new
PacketCombineRsp
(
req
,
toItemParamList
(
result
.
getMaterial
()),
toItemParamList
(
result
.
getResult
()),
toItemParamList
(
result
.
getExtra
()),
toItemParamList
(
result
.
getBack
()),
toItemParamList
(
result
.
getBack
())));
}
private
List
<
ItemParamOuterClass
.
ItemParam
>
toItemParamList
(
List
<
CombineData
.
CombineItemPair
>
list
){
return
list
.
stream
()
.
map
(
item
->
ItemParamOuterClass
.
ItemParam
.
newBuilder
()
.
setItemId
(
item
.
getId
())
.
setCount
(
item
.
getCount
())
.
build
())
.
collect
(
Collectors
.
toList
());
}
}
src/main/java/emu/grasscutter/server/packet/recv/HandlerDelMailReq.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.server.packet.recv
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.net.packet.Opcodes
;
import
emu.grasscutter.net.packet.PacketHandler
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.DelMailReqOuterClass
;
import
emu.grasscutter.net.proto.DeleteFriendReqOuterClass
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.PacketDelMailRsp
;
@Opcodes
(
PacketOpcodes
.
DelMailReq
)
public
class
HandlerDelMailReq
extends
PacketHandler
{
@Override
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
DelMailReqOuterClass
.
DelMailReq
req
=
DelMailReqOuterClass
.
DelMailReq
.
parseFrom
(
payload
);
session
.
getPlayer
().
getMailHandler
().
deleteMail
(
req
.
getMailIdListList
());
}
}
src/main/java/emu/grasscutter/server/packet/recv/HandlerDungeonEntryInfoReq.java
View file @
01b190bc
...
...
@@ -2,6 +2,7 @@ package emu.grasscutter.server.packet.recv;
import
emu.grasscutter.net.packet.Opcodes
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.DungeonEntryInfoReqOuterClass.DungeonEntryInfoReq
;
import
emu.grasscutter.net.packet.PacketHandler
;
import
emu.grasscutter.server.game.GameSession
;
...
...
@@ -10,7 +11,9 @@ public class HandlerDungeonEntryInfoReq extends PacketHandler {
@Override
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
DungeonEntryInfoReq
req
=
DungeonEntryInfoReq
.
parseFrom
(
payload
);
session
.
getServer
().
getDungeonManager
().
getEntryInfo
(
session
.
getPlayer
(),
req
.
getPointId
());
}
}
Prev
1
…
9
10
11
12
13
14
15
16
17
…
25
Next
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