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
d32f706c
Commit
d32f706c
authored
Apr 27, 2022
by
KingRainbow44
Browse files
Merge branch 'development' into api
# Conflicts: # src/main/java/emu/grasscutter/plugin/api/ServerHook.java
parents
47d8fd3c
f0d728b4
Changes
308
Hide whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/netty/
Mihoyo
KcpChannel.java
→
src/main/java/emu/grasscutter/netty/KcpChannel.java
View file @
d32f706c
...
...
@@ -8,7 +8,7 @@ import io.netty.buffer.Unpooled;
import
io.netty.channel.ChannelHandlerContext
;
import
io.netty.channel.ChannelInboundHandlerAdapter
;
public
abstract
class
Mihoyo
KcpChannel
extends
ChannelInboundHandlerAdapter
{
public
abstract
class
KcpChannel
extends
ChannelInboundHandlerAdapter
{
private
UkcpChannel
kcpChannel
;
private
ChannelHandlerContext
ctx
;
private
boolean
isActive
;
...
...
src/main/java/emu/grasscutter/netty/
Mihoyo
KcpHandshaker.java
→
src/main/java/emu/grasscutter/netty/KcpHandshaker.java
View file @
d32f706c
...
...
@@ -10,9 +10,9 @@ import io.netty.channel.ChannelMetadata;
import
io.netty.channel.ChannelOutboundBuffer
;
import
io.netty.channel.nio.AbstractNioMessageChannel
;
public
class
Mihoyo
KcpHandshaker
extends
AbstractNioMessageChannel
{
public
class
KcpHandshaker
extends
AbstractNioMessageChannel
{
protected
Mihoyo
KcpHandshaker
(
Channel
parent
,
SelectableChannel
ch
,
int
readInterestOp
)
{
protected
KcpHandshaker
(
Channel
parent
,
SelectableChannel
ch
,
int
readInterestOp
)
{
super
(
parent
,
ch
,
readInterestOp
);
}
...
...
src/main/java/emu/grasscutter/netty/
Mihoyo
KcpServer.java
→
src/main/java/emu/grasscutter/netty/KcpServer.java
View file @
d32f706c
...
...
@@ -13,14 +13,14 @@ import io.netty.channel.EventLoopGroup;
import
io.netty.channel.nio.NioEventLoopGroup
;
@SuppressWarnings
(
"rawtypes"
)
public
class
Mihoyo
KcpServer
extends
Thread
{
public
class
KcpServer
extends
Thread
{
private
EventLoopGroup
group
;
private
UkcpServerBootstrap
bootstrap
;
private
ChannelInitializer
serverInitializer
;
private
InetSocketAddress
address
;
public
Mihoyo
KcpServer
(
InetSocketAddress
address
)
{
public
KcpServer
(
InetSocketAddress
address
)
{
this
.
address
=
address
;
this
.
setName
(
"Netty Server Thread"
);
}
...
...
@@ -40,7 +40,7 @@ public class MihoyoKcpServer extends Thread {
@Override
public
void
run
()
{
if
(
getServerInitializer
()
==
null
)
{
this
.
setServerInitializer
(
new
Mihoyo
KcpServerInitializer
());
this
.
setServerInitializer
(
new
KcpServerInitializer
());
}
try
{
...
...
src/main/java/emu/grasscutter/netty/
Mihoyo
KcpServerInitializer.java
→
src/main/java/emu/grasscutter/netty/KcpServerInitializer.java
View file @
d32f706c
...
...
@@ -5,7 +5,7 @@ import io.netty.channel.ChannelInitializer;
import
io.netty.channel.ChannelPipeline
;
@SuppressWarnings
(
"unused"
)
public
class
Mihoyo
KcpServerInitializer
extends
ChannelInitializer
<
UkcpChannel
>
{
public
class
KcpServerInitializer
extends
ChannelInitializer
<
UkcpChannel
>
{
@Override
protected
void
initChannel
(
UkcpChannel
ch
)
throws
Exception
{
...
...
src/main/java/emu/grasscutter/plugin/api/PlayerHook.java
View file @
d32f706c
package
emu.grasscutter.plugin.api
;
import
emu.grasscutter.game.GenshinPlayer
;
import
emu.grasscutter.game.avatar.GenshinAvatar
;
import
emu.grasscutter.game.avatar.Avatar
;
import
emu.grasscutter.game.entity.EntityAvatar
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.props.EnterReason
;
import
emu.grasscutter.game.props.FightProperty
;
import
emu.grasscutter.net.packet.
Genshin
Packet
;
import
emu.grasscutter.net.packet.
Base
Packet
;
import
emu.grasscutter.net.proto.EnterTypeOuterClass.EnterType
;
import
emu.grasscutter.server.packet.send.PacketAvatarFightPropUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketAvatarLifeStateChangeNotify
;
...
...
@@ -13,16 +13,16 @@ import emu.grasscutter.server.packet.send.PacketPlayerEnterSceneNotify;
import
emu.grasscutter.utils.Position
;
/**
* Hooks into the {@link
Genshin
Player} class, adding convenient ways to do certain things.
* Hooks into the {@link Player} class, adding convenient ways to do certain things.
*/
public
final
class
PlayerHook
{
private
final
Genshin
Player
player
;
private
final
Player
player
;
/**
* Hooks into the player.
* @param player The player to hook into.
*/
public
PlayerHook
(
Genshin
Player
player
)
{
public
PlayerHook
(
Player
player
)
{
this
.
player
=
player
;
}
...
...
@@ -53,7 +53,7 @@ public final class PlayerHook {
* Broadcasts the packet sent to all world players.
* @param packet The packet to send.
*/
public
void
broadcastPacketToWorld
(
Genshin
Packet
packet
)
{
public
void
broadcastPacketToWorld
(
Base
Packet
packet
)
{
this
.
player
.
getWorld
().
broadcastPacket
(
packet
);
}
...
...
@@ -70,7 +70,7 @@ public final class PlayerHook {
* Revives the specified avatar.
* @param avatar The avatar to revive.
*/
public
void
reviveAvatar
(
Genshin
Avatar
avatar
)
{
public
void
reviveAvatar
(
Avatar
avatar
)
{
this
.
broadcastPacketToWorld
(
new
PacketAvatarLifeStateChangeNotify
(
avatar
));
}
...
...
@@ -82,7 +82,7 @@ public final class PlayerHook {
public
void
teleport
(
Position
position
)
{
this
.
player
.
getPos
().
set
(
position
);
this
.
player
.
sendPacket
(
new
PacketPlayerEnterSceneNotify
(
this
.
player
,
EnterType
.
E
nterJump
,
EnterReason
.
TransPoint
,
EnterType
.
E
NTER_JUMP
,
EnterReason
.
TransPoint
,
this
.
player
.
getSceneId
(),
position
));
}
...
...
@@ -105,9 +105,9 @@ public final class PlayerHook {
/**
* Gets the currently selected avatar.
* @return The avatar as an {@link
Genshin
Avatar}.
* @return The avatar as an {@link Avatar}.
*/
public
Genshin
Avatar
getCurrentAvatar
()
{
public
Avatar
getCurrentAvatar
()
{
return
this
.
getCurrentAvatarEntity
().
getAvatar
();
}
}
\ No newline at end of file
src/main/java/emu/grasscutter/server/dispatch/DispatchServer.java
View file @
d32f706c
...
...
@@ -55,9 +55,14 @@ public final class DispatchServer {
this
.
initRegion
();
}
@Deprecated
public
HttpServer
getServer
()
{
return
server
;
}
public
HttpServer
getHttpServer
()
{
return
server
;
}
public
InetSocketAddress
getAddress
()
{
return
address
;
...
...
@@ -126,10 +131,10 @@ public final class DispatchServer {
servers
.
add
(
server
);
RegionInfo
serverRegion
=
regionQuery
.
getRegionInfo
().
toBuilder
()
.
setIp
((
Grasscutter
.
getConfig
().
getGameServerOptions
().
PublicIp
.
isEmpty
()
.
set
Gateserver
Ip
((
Grasscutter
.
getConfig
().
getGameServerOptions
().
PublicIp
.
isEmpty
()
?
Grasscutter
.
getConfig
().
getGameServerOptions
().
Ip
:
Grasscutter
.
getConfig
().
getGameServerOptions
().
PublicIp
))
.
setPort
(
Grasscutter
.
getConfig
().
getGameServerOptions
().
PublicPort
!=
0
.
set
Gateserver
Port
(
Grasscutter
.
getConfig
().
getGameServerOptions
().
PublicPort
!=
0
?
Grasscutter
.
getConfig
().
getGameServerOptions
().
PublicPort
:
Grasscutter
.
getConfig
().
getGameServerOptions
().
Port
)
.
setSecretKey
(
ByteString
...
...
@@ -169,8 +174,8 @@ public final class DispatchServer {
servers
.
add
(
server
);
RegionInfo
serverRegion
=
regionQuery
.
getRegionInfo
().
toBuilder
()
.
setIp
(
regionInfo
.
Ip
)
.
setPort
(
regionInfo
.
Port
)
.
set
Gateserver
Ip
(
regionInfo
.
Ip
)
.
set
Gateserver
Port
(
regionInfo
.
Port
)
.
setSecretKey
(
ByteString
.
copyFrom
(
FileUtils
.
read
(
Grasscutter
.
getConfig
().
KEY_FOLDER
+
"dispatchSeed.bin"
)))
.
build
();
...
...
@@ -181,7 +186,7 @@ public final class DispatchServer {
}
QueryRegionListHttpRsp
regionList
=
QueryRegionListHttpRsp
.
newBuilder
()
.
addAll
Servers
(
servers
)
.
addAll
RegionList
(
servers
)
.
setClientSecretKey
(
rl
.
getClientSecretKey
())
.
setClientCustomConfigEncrypted
(
rl
.
getClientCustomConfigEncrypted
())
.
setEnableLoginPc
(
true
)
...
...
@@ -203,56 +208,65 @@ public final class DispatchServer {
}
return
null
;
}
private
KeyManagerFactory
createKeyManagerFactory
(
File
keystore
,
String
password
)
throws
Exception
{
char
[]
pass
=
password
.
toCharArray
();
KeyManagerFactory
kmf
=
null
;
try
(
FileInputStream
fis
=
new
FileInputStream
(
keystore
))
{
KeyStore
ks
=
KeyStore
.
getInstance
(
"PKCS12"
);
ks
.
load
(
fis
,
pass
);
kmf
=
KeyManagerFactory
.
getInstance
(
"SunX509"
);
kmf
.
init
(
ks
,
pass
);
}
catch
(
Exception
e
)
{
throw
e
;
}
return
kmf
;
}
public
void
start
()
throws
Exception
{
if
(
Grasscutter
.
getConfig
().
getDispatchOptions
().
UseSSL
)
{
HttpsServer
httpsServer
=
HttpsServer
.
create
(
getAddress
(),
0
);
// Keystore
SSLContext
sslContext
=
SSLContext
.
getInstance
(
"TLS"
);
try
(
FileInputStream
fis
=
new
FileInputStream
(
Grasscutter
.
getConfig
().
getDispatchOptions
().
KeystorePath
))
{
char
[]
keystorePassword
=
Grasscutter
.
getConfig
().
getDispatchOptions
().
KeystorePassword
.
toCharArray
();
KeyManagerFactory
_kmf
;
KeyManagerFactory
kmf
=
null
;
File
keystoreFile
=
new
File
(
Grasscutter
.
getConfig
().
getDispatchOptions
().
KeystorePath
);
if
(
keystoreFile
.
exists
())
{
try
{
KeyStore
ks
=
KeyStore
.
getInstance
(
"PKCS12"
);
ks
.
load
(
fis
,
keystorePassword
);
KeyManagerFactory
kmf
=
KeyManagerFactory
.
getInstance
(
"SunX509"
);
_kmf
=
kmf
;
kmf
.
init
(
ks
,
keystorePassword
);
}
catch
(
Exception
originalEx
)
{
kmf
=
createKeyManagerFactory
(
keystoreFile
,
Grasscutter
.
getConfig
().
getDispatchOptions
().
KeystorePassword
);
}
catch
(
Exception
e
)
{
Grasscutter
.
getLogger
().
warn
(
"[Dispatch] Unable to load keystore. Trying default keystore password..."
);
try
{
// try to initialize kmf with the default password
char
[]
defaultPassword
=
"123456"
.
toCharArray
();
Grasscutter
.
getLogger
()
.
warn
(
"[Dispatch] Unable to load keystore. Trying default keystore password..."
);
KeyStore
ks
=
KeyStore
.
getInstance
(
"PKCS12"
);
ks
.
load
(
fis
,
defaultPassword
);
KeyManagerFactory
kmf
=
KeyManagerFactory
.
getInstance
(
"SunX509"
);
kmf
.
init
(
ks
,
defaultPassword
);
_kmf
=
kmf
;
kmf
=
createKeyManagerFactory
(
keystoreFile
,
"123456"
);
Grasscutter
.
getLogger
().
warn
(
"[Dispatch] The default keystore password was loaded successfully. Please consider setting the password in config.json."
);
}
catch
(
Exception
ignored
)
{
"[Dispatch] The default keystore password was loaded successfully. Please consider setting the password
to 123456
in config.json."
);
}
catch
(
Exception
e2
)
{
Grasscutter
.
getLogger
().
warn
(
"[Dispatch] Error while loading keystore!"
);
// don't care about the exception for the "123456" default password attempt
originalEx
.
printStackTrace
();
throw
originalEx
;
e2
.
printStackTrace
();
}
}
sslContext
.
init
(
_kmf
.
getKeyManagers
(),
null
,
null
);
httpsServer
.
setHttpsConfigurator
(
new
HttpsConfigurator
(
sslContext
));
server
=
httpsServer
;
}
catch
(
BindException
ignored
)
{
Grasscutter
.
getLogger
().
error
(
"Unable to bind to port: "
+
getAddress
().
getPort
()
+
" (HTTPS)"
);
server
=
this
.
safelyCreateServer
(
this
.
getAddress
());
}
catch
(
Exception
e
)
{
}
if
(
kmf
==
null
)
{
Grasscutter
.
getLogger
().
warn
(
"[Dispatch] No SSL cert found! Falling back to HTTP server."
);
Grasscutter
.
getConfig
().
getDispatchOptions
().
UseSSL
=
false
;
server
=
this
.
safelyCreateServer
(
this
.
getAddress
());
}
HttpsServer
httpsServer
=
null
;
try
{
httpsServer
=
HttpsServer
.
create
(
getAddress
(),
0
);
sslContext
.
init
(
kmf
.
getKeyManagers
(),
null
,
null
);
httpsServer
.
setHttpsConfigurator
(
new
HttpsConfigurator
(
sslContext
));
server
=
httpsServer
;
}
catch
(
BindException
e
)
{
Grasscutter
.
getLogger
().
error
(
"Unable to bind to port: "
+
getAddress
().
getPort
()
+
" (HTTPS)"
);
}
}
else
{
server
=
this
.
safelyCreateServer
(
this
.
getAddress
());
}
...
...
src/main/java/emu/grasscutter/server/event/game/SendPacketEvent.java
View file @
d32f706c
package
emu.grasscutter.server.event.game
;
import
emu.grasscutter.net.packet.
Genshin
Packet
;
import
emu.grasscutter.net.packet.
Base
Packet
;
import
emu.grasscutter.server.event.Cancellable
;
import
emu.grasscutter.server.event.ServerEvent
;
import
emu.grasscutter.server.game.GameSession
;
public
final
class
SendPacketEvent
extends
ServerEvent
implements
Cancellable
{
private
final
GameSession
gameSession
;
private
Genshin
Packet
packet
;
private
Base
Packet
packet
;
public
SendPacketEvent
(
GameSession
gameSession
,
Genshin
Packet
packet
)
{
public
SendPacketEvent
(
GameSession
gameSession
,
Base
Packet
packet
)
{
super
(
Type
.
GAME
);
this
.
gameSession
=
gameSession
;
...
...
@@ -20,11 +20,11 @@ public final class SendPacketEvent extends ServerEvent implements Cancellable {
return
this
.
gameSession
;
}
public
void
setPacket
(
Genshin
Packet
packet
)
{
public
void
setPacket
(
Base
Packet
packet
)
{
this
.
packet
=
packet
;
}
public
Genshin
Packet
getPacket
()
{
public
Base
Packet
getPacket
()
{
return
this
.
packet
;
}
}
src/main/java/emu/grasscutter/server/game/GameServer.java
View file @
d32f706c
package
emu.grasscutter.server.game
;
import
java.net.InetSocketAddress
;
import
java.time.OffsetDateTime
;
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.World
;
import
emu.grasscutter.game.drop.DropManager
;
import
emu.grasscutter.game.dungeons.DungeonManager
;
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.
Mihoyo
KcpServer
;
import
emu.grasscutter.netty.KcpServer
;
import
emu.grasscutter.server.event.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
;
public
final
class
GameServer
extends
Mihoyo
KcpServer
{
public
final
class
GameServer
extends
KcpServer
{
private
final
InetSocketAddress
address
;
private
final
GameServerPacketHandler
packetHandler
;
private
final
Map
<
Integer
,
Genshin
Player
>
players
;
private
final
Map
<
Integer
,
Player
>
players
;
private
final
Set
<
World
>
worlds
;
private
final
ChatManager
chatManager
;
...
...
@@ -40,6 +42,8 @@ public final class GameServer extends MihoyoKcpServer {
private
final
MultiplayerManager
multiplayerManager
;
private
final
DungeonManager
dungeonManager
;
private
final
CommandMap
commandMap
;
private
final
TaskMap
taskMap
;
private
final
DropManager
dropManager
;
public
GameServer
(
InetSocketAddress
address
)
{
super
(
address
);
...
...
@@ -57,6 +61,8 @@ public final class GameServer extends MihoyoKcpServer {
this
.
multiplayerManager
=
new
MultiplayerManager
(
this
);
this
.
dungeonManager
=
new
DungeonManager
(
this
);
this
.
commandMap
=
new
CommandMap
(
true
);
this
.
taskMap
=
new
TaskMap
(
true
);
this
.
dropManager
=
new
DropManager
(
this
);
// Schedule game loop.
Timer
gameLoop
=
new
Timer
();
...
...
@@ -79,7 +85,7 @@ public final class GameServer extends MihoyoKcpServer {
return
packetHandler
;
}
public
Map
<
Integer
,
Genshin
Player
>
getPlayers
()
{
public
Map
<
Integer
,
Player
>
getPlayers
()
{
return
players
;
}
...
...
@@ -106,6 +112,10 @@ public final class GameServer extends MihoyoKcpServer {
public
MultiplayerManager
getMultiplayerManager
()
{
return
multiplayerManager
;
}
public
DropManager
getDropManager
()
{
return
dropManager
;
}
public
DungeonManager
getDungeonManager
()
{
return
dungeonManager
;
...
...
@@ -114,23 +124,27 @@ public final class GameServer extends MihoyoKcpServer {
public
CommandMap
getCommandMap
()
{
return
this
.
commandMap
;
}
public
TaskMap
getTaskMap
()
{
return
this
.
taskMap
;
}
public
void
registerPlayer
(
Genshin
Player
player
)
{
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
;
...
...
@@ -146,7 +160,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
;
...
...
@@ -156,7 +170,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
();
}
...
...
@@ -197,10 +211,10 @@ public final class GameServer extends MihoyoKcpServer {
ServerStopEvent
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 @
d32f706c
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 @
d32f706c
...
...
@@ -89,7 +89,7 @@ public class GameServerPacketHandler {
// Log unhandled packets
if
(
Grasscutter
.
getConfig
().
getGameServerOptions
().
LOG_PACKETS
)
{
//
Grasscutter.getLogger().info("Unhandled packet (" + opcode + "): " + PacketOpcodesUtil.getOpcodeName(opcode));
Grasscutter
.
getLogger
().
info
(
"Unhandled packet ("
+
opcode
+
"): "
+
emu
.
grasscutter
.
net
.
packet
.
PacketOpcodesUtil
.
getOpcodeName
(
opcode
));
}
}
}
src/main/java/emu/grasscutter/server/game/GameSession.java
View file @
d32f706c
...
...
@@ -3,13 +3,16 @@ 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.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.
Mihoyo
KcpChannel
;
import
emu.grasscutter.netty.KcpChannel
;
import
emu.grasscutter.server.event.game.SendPacketEvent
;
import
emu.grasscutter.utils.Crypto
;
import
emu.grasscutter.utils.FileUtils
;
...
...
@@ -18,11 +21,11 @@ import io.netty.buffer.ByteBuf;
import
io.netty.buffer.Unpooled
;
import
io.netty.channel.ChannelHandlerContext
;
public
class
GameSession
extends
Mihoyo
KcpChannel
{
public
class
GameSession
extends
KcpChannel
{
private
GameServer
server
;
private
Account
account
;
private
Genshin
Player
player
;
private
Player
player
;
private
boolean
useSecretKey
;
private
SessionState
state
;
...
...
@@ -64,11 +67,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
());
...
...
@@ -141,46 +144,48 @@ public class GameSession extends MihoyoKcpChannel {
byte
[]
packet
=
FileUtils
.
read
(
p
);
GenshinPacket
genshin
Packet
=
new
Genshin
Packet
(
opcode
);
genshin
Packet
.
setData
(
packet
);
BasePacket
base
Packet
=
new
Base
Packet
(
opcode
);
base
Packet
.
setData
(
packet
);
// Log
logPacket
(
genshinPacket
.
getOpcode
());
send
(
genshinPacket
);
send
(
basePacket
);
}
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
(
genshinP
acket
.
shouldBuildHeader
())
{
genshinP
acket
.
buildHeader
(
this
.
getNextClientSequence
());
if
(
p
acket
.
shouldBuildHeader
())
{
p
acket
.
buildHeader
(
this
.
getNextClientSequence
());
}
// Log
if
(
Grasscutter
.
getConfig
().
getGameServerOptions
().
LOG_PACKETS
)
{
logPacket
(
genshinP
acket
);
logPacket
(
p
acket
);
}
// Invoke event.
SendPacketEvent
event
=
new
SendPacketEvent
(
this
,
genshinP
acket
);
event
.
call
();
SendPacketEvent
event
=
new
SendPacketEvent
(
this
,
p
acket
);
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
void
logPacket
(
GenshinPacket
genshinPacket
)
{
Grasscutter
.
getLogger
().
info
(
"SEND: "
+
PacketOpcodesUtil
.
getOpcodeName
(
genshinPacket
.
getOpcode
())
+
" ("
+
genshinPacket
.
getOpcode
()
+
")"
);
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
(
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
...
...
@@ -226,8 +231,10 @@ public class GameSession extends MihoyoKcpChannel {
// Log packet
if
(
Grasscutter
.
getConfig
().
getGameServerOptions
().
LOG_PACKETS
)
{
Grasscutter
.
getLogger
().
info
(
"RECV: "
+
PacketOpcodesUtil
.
getOpcodeName
(
opcode
)
+
" ("
+
opcode
+
")"
);
System
.
out
.
println
(
Utils
.
bytesToHex
(
payload
));
if
(!
loopPacket
.
contains
(
opcode
))
{
Grasscutter
.
getLogger
().
info
(
"RECV: "
+
PacketOpcodesUtil
.
getOpcodeName
(
opcode
)
+
" ("
+
opcode
+
")"
);
System
.
out
.
println
(
Utils
.
bytesToHex
(
payload
));
}
}
// Handle
...
...
src/main/java/emu/grasscutter/server/packet/recv/HandlerAvatarFetterLevelRewardReq.java
View file @
d32f706c
package
emu.grasscutter.server.packet.recv
;
import
emu.grasscutter.data.G
enshin
Data
;
import
emu.grasscutter.data.G
ame
Data
;
import
emu.grasscutter.data.def.RewardData
;
import
emu.grasscutter.game.avatar.
Genshin
Avatar
;
import
emu.grasscutter.game.inventory.G
enshin
Item
;
import
emu.grasscutter.game.avatar.Avatar
;
import
emu.grasscutter.game.inventory.G
ame
Item
;
import
emu.grasscutter.game.props.ActionReason
;
import
emu.grasscutter.net.packet.Opcodes
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
...
...
@@ -27,14 +27,14 @@ public class HandlerAvatarFetterLevelRewardReq extends PacketHandler {
}
else
{
long
avatarGuid
=
req
.
getAvatarGuid
();
Genshin
Avatar
avatar
=
session
Avatar
avatar
=
session
.
getPlayer
()
.
getAvatars
()
.
getAvatarByGuid
(
avatarGuid
);
int
rewardId
=
avatar
.
getNameCardRewardId
();
RewardData
card
=
G
enshin
Data
.
getRewardDataMap
().
get
(
rewardId
);
RewardData
card
=
G
ame
Data
.
getRewardDataMap
().
get
(
rewardId
);
int
cardId
=
card
.
getRewardItemList
().
get
(
0
).
getItemId
();
if
(
session
.
getPlayer
().
getNameCardList
().
contains
(
cardId
))
{
...
...
@@ -43,9 +43,8 @@ public class HandlerAvatarFetterLevelRewardReq extends PacketHandler {
return
;
}
GenshinItem
item
=
new
GenshinItem
(
cardId
);
session
.
getPlayer
().
getInventory
().
addItem
(
item
);
session
.
getPlayer
().
sendPacket
(
new
PacketItemAddHintNotify
(
item
,
ActionReason
.
FetterLevelReward
));
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
()));
...
...
src/main/java/emu/grasscutter/server/packet/recv/HandlerBuyGoodsReq.java
0 → 100644
View file @
d32f706c
package
emu.grasscutter.server.packet.recv
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.game.inventory.GameItem
;
import
emu.grasscutter.game.props.ActionReason
;
import
emu.grasscutter.game.props.PlayerProperty
;
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
java.util.ArrayList
;
import
java.util.HashMap
;
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
);
for
(
ShopGoodsOuterClass
.
ShopGoods
sg
:
buyGoodsReq
.
getGoodsListList
())
{
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
().
getProperty
(
PlayerProperty
.
PROP_PLAYER_MCOIN
)
<
buyGoodsReq
.
getBoughtNum
()
*
sg
.
getMcoin
())
{
return
;
}
HashMap
<
GameItem
,
Integer
>
itemsCache
=
new
HashMap
<>();
for
(
ItemParamOuterClass
.
ItemParam
p
:
sg
.
getCostItemListList
())
{
Optional
<
GameItem
>
invItem
=
session
.
getPlayer
().
getInventory
().
getItems
().
values
().
stream
().
filter
(
x
->
x
.
getItemId
()
==
p
.
getItemId
()).
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
().
setProperty
(
PlayerProperty
.
PROP_PLAYER_MCOIN
,
session
.
getPlayer
().
getProperty
(
PlayerProperty
.
PROP_PLAYER_MCOIN
)
-
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
());
GameItem
item
=
new
GameItem
(
GameData
.
getItemDataMap
().
get
(
sg
.
getGoodsItem
().
getItemId
()));
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
().
getGoodsLimitNum
(
sg
.
getGoodsId
()),
sg
));
}
session
.
getPlayer
().
save
();
}
}
src/main/java/emu/grasscutter/server/packet/recv/HandlerChangeMailStarNotify.java
0 → 100644
View file @
d32f706c
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 @
d32f706c
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
;
...
...
@@ -19,15 +19,15 @@ public class HandlerCombatInvocationsNotify extends PacketHandler {
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
().
getScene
().
handleAttack
(
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
());
...
...
src/main/java/emu/grasscutter/server/packet/recv/Handle
Sit
Req.java
→
src/main/java/emu/grasscutter/server/packet/recv/Handle
rCombine
Req.java
View file @
d32f706c
...
...
@@ -3,22 +3,18 @@ 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.
Sit
ReqOuterClass
;
import
emu.grasscutter.net.proto.
Combine
ReqOuterClass
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.PacketSitRsp
;
import
emu.grasscutter.utils.Position
;
@Opcodes
(
PacketOpcodes
.
SitReq
)
public
class
HandleSitReq
extends
PacketHandler
{
@Opcodes
(
PacketOpcodes
.
CombineReq
)
public
class
HandlerCombineReq
extends
PacketHandler
{
@Override
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
SitReqOuterClass
.
SitReq
req
=
SitReqOuterClass
.
SitReq
.
parseFrom
(
payload
);
float
x
=
req
.
getPosition
().
getX
();
float
y
=
req
.
getPosition
().
getY
();
float
z
=
req
.
getPosition
().
getZ
();
CombineReqOuterClass
.
CombineReq
req
=
CombineReqOuterClass
.
CombineReq
.
parseFrom
(
payload
);
session
.
send
(
new
PacketSitRsp
(
req
.
getChairId
(),
new
Position
(
x
,
y
,
z
),
session
.
getPlayer
().
getTeamManager
().
getCurrentAvatarEntity
().
getId
()));
}
}
\ No newline at end of file
}
src/main/java/emu/grasscutter/server/packet/recv/HandlerDelMailReq.java
0 → 100644
View file @
d32f706c
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.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
.
send
(
new
PacketDelMailRsp
(
session
.
getPlayer
(),
req
.
getMailIdListList
()));
}
}
src/main/java/emu/grasscutter/server/packet/recv/HandlerEnterSceneDoneReq.java
View file @
d32f706c
package
emu.grasscutter.server.packet.recv
;
import
emu.grasscutter.game.
Genshin
Player.SceneLoadState
;
import
emu.grasscutter.game.
player.
Player.SceneLoadState
;
import
emu.grasscutter.net.packet.Opcodes
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.packet.PacketHandler
;
...
...
src/main/java/emu/grasscutter/server/packet/recv/HandleEvtAvatarSitDownNotify.java
→
src/main/java/emu/grasscutter/server/packet/recv/Handle
r
EvtAvatarSitDownNotify.java
View file @
d32f706c
...
...
@@ -8,7 +8,7 @@ import emu.grasscutter.server.game.GameSession;
import
emu.grasscutter.server.packet.send.PacketEvtAvatarSitDownNotify
;
@Opcodes
(
PacketOpcodes
.
EvtAvatarSitDownNotify
)
public
class
HandleEvtAvatarSitDownNotify
extends
PacketHandler
{
public
class
Handle
r
EvtAvatarSitDownNotify
extends
PacketHandler
{
@Override
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
...
...
src/main/java/emu/grasscutter/server/packet/recv/HandlerGetAllMailReq.java
0 → 100644
View file @
d32f706c
package
emu.grasscutter.server.packet.recv
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.net.packet.Opcodes
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.packet.PacketHandler
;
import
emu.grasscutter.net.proto.GetAllMailReqOuterClass
;
import
emu.grasscutter.net.proto.GetPlayerTokenReqOuterClass
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.PacketGetAllMailRsp
;
import
emu.grasscutter.server.packet.send.PacketGetGachaInfoRsp
;
@Opcodes
(
PacketOpcodes
.
GetAllMailReq
)
public
class
HandlerGetAllMailReq
extends
PacketHandler
{
@Override
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
GetAllMailReqOuterClass
.
GetAllMailReq
req
=
GetAllMailReqOuterClass
.
GetAllMailReq
.
parseFrom
(
payload
);
session
.
send
(
new
PacketGetAllMailRsp
(
session
.
getPlayer
(),
req
.
getIsGiftMail
()));
}
}
Prev
1
…
3
4
5
6
7
8
9
10
11
…
16
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