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
fa9d703d
Commit
fa9d703d
authored
Apr 27, 2022
by
BaiSugar
Committed by
GitHub
Apr 27, 2022
Browse files
Merge branch 'Grasscutters:development' into development
parents
6a5d97a3
d1fc8c1f
Changes
279
Hide whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/game/World.java
→
src/main/java/emu/grasscutter/game/
world/
World.java
View file @
fa9d703d
package
emu.grasscutter.game
;
package
emu.grasscutter.game
.world
;
import
java.util.ArrayList
;
import
java.util.Collection
;
...
...
@@ -8,19 +8,20 @@ import java.util.LinkedList;
import
java.util.List
;
import
java.util.stream.Collectors
;
import
emu.grasscutter.game.entity.GenshinEntity
;
import
emu.grasscutter.game.entity.GameEntity
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.player.Player.SceneLoadState
;
import
emu.grasscutter.game.props.ClimateType
;
import
emu.grasscutter.game.props.EnterReason
;
import
emu.grasscutter.game.props.EntityIdType
;
import
emu.grasscutter.game.props.FightProperty
;
import
emu.grasscutter.game.props.LifeState
;
import
emu.grasscutter.data.G
enshin
Data
;
import
emu.grasscutter.data.G
ame
Data
;
import
emu.grasscutter.data.def.SceneData
;
import
emu.grasscutter.game.GenshinPlayer.SceneLoadState
;
import
emu.grasscutter.game.entity.EntityAvatar
;
import
emu.grasscutter.game.entity.EntityClientGadget
;
import
emu.grasscutter.game.entity.EntityGadget
;
import
emu.grasscutter.net.packet.
Genshin
Packet
;
import
emu.grasscutter.net.packet.
Base
Packet
;
import
emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult
;
import
emu.grasscutter.net.proto.EnterTypeOuterClass.EnterType
;
import
emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType
;
...
...
@@ -40,10 +41,10 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import
it.unimi.dsi.fastutil.ints.Int2ObjectMaps
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
;
public
class
World
implements
Iterable
<
Genshin
Player
>
{
private
final
Genshin
Player
owner
;
private
final
List
<
Genshin
Player
>
players
;
private
final
Int2ObjectMap
<
Genshin
Scene
>
scenes
;
public
class
World
implements
Iterable
<
Player
>
{
private
final
Player
owner
;
private
final
List
<
Player
>
players
;
private
final
Int2ObjectMap
<
Scene
>
scenes
;
private
int
levelEntityId
;
private
int
nextEntityId
=
0
;
...
...
@@ -52,11 +53,11 @@ public class World implements Iterable<GenshinPlayer> {
private
boolean
isMultiplayer
;
public
World
(
Genshin
Player
player
)
{
public
World
(
Player
player
)
{
this
(
player
,
false
);
}
public
World
(
Genshin
Player
player
,
boolean
isMultiplayer
)
{
public
World
(
Player
player
,
boolean
isMultiplayer
)
{
this
.
owner
=
player
;
this
.
players
=
Collections
.
synchronizedList
(
new
ArrayList
<>());
this
.
scenes
=
Int2ObjectMaps
.
synchronize
(
new
Int2ObjectOpenHashMap
<>());
...
...
@@ -68,7 +69,7 @@ public class World implements Iterable<GenshinPlayer> {
this
.
owner
.
getServer
().
registerWorld
(
this
);
}
public
Genshin
Player
getHost
()
{
public
Player
getHost
()
{
return
owner
;
}
...
...
@@ -95,25 +96,25 @@ public class World implements Iterable<GenshinPlayer> {
this
.
worldLevel
=
worldLevel
;
}
public
List
<
Genshin
Player
>
getPlayers
()
{
public
List
<
Player
>
getPlayers
()
{
return
players
;
}
public
Int2ObjectMap
<
Genshin
Scene
>
getScenes
()
{
public
Int2ObjectMap
<
Scene
>
getScenes
()
{
return
this
.
scenes
;
}
public
Genshin
Scene
getSceneById
(
int
sceneId
)
{
public
Scene
getSceneById
(
int
sceneId
)
{
// Get scene normally
Genshin
Scene
scene
=
getScenes
().
get
(
sceneId
);
Scene
scene
=
getScenes
().
get
(
sceneId
);
if
(
scene
!=
null
)
{
return
scene
;
}
// Create scene from scene data if it doesnt exist
SceneData
sceneData
=
G
enshin
Data
.
getSceneDataMap
().
get
(
sceneId
);
SceneData
sceneData
=
G
ame
Data
.
getSceneDataMap
().
get
(
sceneId
);
if
(
sceneData
!=
null
)
{
scene
=
new
Genshin
Scene
(
this
,
sceneData
);
scene
=
new
Scene
(
this
,
sceneData
);
this
.
registerScene
(
scene
);
return
scene
;
}
...
...
@@ -133,7 +134,7 @@ public class World implements Iterable<GenshinPlayer> {
return
(
idType
.
getId
()
<<
24
)
+
++
this
.
nextEntityId
;
}
public
synchronized
void
addPlayer
(
Genshin
Player
player
)
{
public
synchronized
void
addPlayer
(
Player
player
)
{
// Check if player already in
if
(
getPlayers
().
contains
(
player
))
{
return
;
...
...
@@ -159,7 +160,7 @@ public class World implements Iterable<GenshinPlayer> {
}
// Add to scene
Genshin
Scene
scene
=
this
.
getSceneById
(
player
.
getSceneId
());
Scene
scene
=
this
.
getSceneById
(
player
.
getSceneId
());
scene
.
addPlayer
(
player
);
// Info packet for other players
...
...
@@ -168,7 +169,7 @@ public class World implements Iterable<GenshinPlayer> {
}
}
public
synchronized
void
removePlayer
(
Genshin
Player
player
)
{
public
synchronized
void
removePlayer
(
Player
player
)
{
// Remove team entities
player
.
sendPacket
(
new
PacketDelTeamEntityNotify
(
...
...
@@ -182,7 +183,7 @@ public class World implements Iterable<GenshinPlayer> {
player
.
setWorld
(
null
);
// Remove from scene
Genshin
Scene
scene
=
this
.
getSceneById
(
player
.
getSceneId
());
Scene
scene
=
this
.
getSceneById
(
player
.
getSceneId
());
scene
.
removePlayer
(
player
);
// Info packet for other players
...
...
@@ -192,8 +193,8 @@ public class World implements Iterable<GenshinPlayer> {
// Disband world if host leaves
if
(
getHost
()
==
player
)
{
List
<
Genshin
Player
>
kicked
=
new
ArrayList
<>(
this
.
getPlayers
());
for
(
Genshin
Player
victim
:
kicked
)
{
List
<
Player
>
kicked
=
new
ArrayList
<>(
this
.
getPlayers
());
for
(
Player
victim
:
kicked
)
{
World
world
=
new
World
(
victim
);
world
.
addPlayer
(
victim
);
...
...
@@ -202,20 +203,20 @@ public class World implements Iterable<GenshinPlayer> {
}
}
public
void
registerScene
(
Genshin
Scene
scene
)
{
public
void
registerScene
(
Scene
scene
)
{
this
.
getScenes
().
put
(
scene
.
getId
(),
scene
);
}
public
void
deregisterScene
(
Genshin
Scene
scene
)
{
public
void
deregisterScene
(
Scene
scene
)
{
this
.
getScenes
().
remove
(
scene
.
getId
());
}
public
boolean
transferPlayerToScene
(
Genshin
Player
player
,
int
sceneId
,
Position
pos
)
{
if
(
G
enshin
Data
.
getSceneDataMap
().
get
(
sceneId
)
==
null
)
{
public
boolean
transferPlayerToScene
(
Player
player
,
int
sceneId
,
Position
pos
)
{
if
(
G
ame
Data
.
getSceneDataMap
().
get
(
sceneId
)
==
null
)
{
return
false
;
}
Genshin
Scene
oldScene
=
null
;
Scene
oldScene
=
null
;
if
(
player
.
getScene
()
!=
null
)
{
oldScene
=
player
.
getScene
();
...
...
@@ -228,7 +229,7 @@ public class World implements Iterable<GenshinPlayer> {
oldScene
.
removePlayer
(
player
);
}
Genshin
Scene
newScene
=
this
.
getSceneById
(
sceneId
);
Scene
newScene
=
this
.
getSceneById
(
sceneId
);
newScene
.
addPlayer
(
player
);
player
.
getPos
().
set
(
pos
);
...
...
@@ -245,8 +246,8 @@ public class World implements Iterable<GenshinPlayer> {
return
true
;
}
private
void
updatePlayerInfos
(
Genshin
Player
paramPlayer
)
{
for
(
Genshin
Player
player
:
getPlayers
())
{
private
void
updatePlayerInfos
(
Player
paramPlayer
)
{
for
(
Player
player
:
getPlayers
())
{
// Dont send packets if player is loading in and filter out joining player
if
(!
player
.
hasSentAvatarDataNotify
()
||
player
.
getSceneLoadState
().
getValue
()
<
SceneLoadState
.
INIT
.
getValue
()
||
player
==
paramPlayer
)
{
continue
;
...
...
@@ -269,15 +270,15 @@ public class World implements Iterable<GenshinPlayer> {
}
}
public
void
broadcastPacket
(
Genshin
Packet
packet
)
{
public
void
broadcastPacket
(
Base
Packet
packet
)
{
// Send to all players - might have to check if player has been sent data packets
for
(
Genshin
Player
player
:
this
.
getPlayers
())
{
for
(
Player
player
:
this
.
getPlayers
())
{
player
.
getSession
().
send
(
packet
);
}
}
public
void
onTick
()
{
for
(
Genshin
Scene
scene
:
this
.
getScenes
().
values
())
{
for
(
Scene
scene
:
this
.
getScenes
().
values
())
{
scene
.
onTick
();
}
}
...
...
@@ -287,7 +288,7 @@ public class World implements Iterable<GenshinPlayer> {
}
@Override
public
Iterator
<
Genshin
Player
>
iterator
()
{
public
Iterator
<
Player
>
iterator
()
{
return
getPlayers
().
iterator
();
}
}
src/main/java/emu/grasscutter/net/packet/
Genshin
Packet.java
→
src/main/java/emu/grasscutter/net/packet/
Base
Packet.java
View file @
fa9d703d
...
...
@@ -7,7 +7,7 @@ import com.google.protobuf.GeneratedMessageV3;
import
emu.grasscutter.net.proto.PacketHeadOuterClass.PacketHead
;
import
emu.grasscutter.utils.Crypto
;
public
class
Genshin
Packet
{
public
class
Base
Packet
{
private
static
final
int
const1
=
17767
;
// 0x4567
private
static
final
int
const2
=
-
30293
;
// 0x89ab
...
...
@@ -21,16 +21,16 @@ public class GenshinPacket {
private
boolean
useDispatchKey
;
public
boolean
shouldEncrypt
=
true
;
public
Genshin
Packet
(
int
opcode
)
{
public
Base
Packet
(
int
opcode
)
{
this
.
opcode
=
opcode
;
}
public
Genshin
Packet
(
int
opcode
,
int
clientSequence
)
{
public
Base
Packet
(
int
opcode
,
int
clientSequence
)
{
this
.
opcode
=
opcode
;
this
.
buildHeader
(
clientSequence
);
}
public
Genshin
Packet
(
int
opcode
,
boolean
buildHeader
)
{
public
Base
Packet
(
int
opcode
,
boolean
buildHeader
)
{
this
.
opcode
=
opcode
;
this
.
shouldBuildHeader
=
buildHeader
;
}
...
...
@@ -80,7 +80,7 @@ public class GenshinPacket {
this
.
data
=
proto
.
build
().
toByteArray
();
}
public
Genshin
Packet
buildHeader
(
int
clientSequence
)
{
public
Base
Packet
buildHeader
(
int
clientSequence
)
{
if
(
this
.
getHeader
()
!=
null
&&
clientSequence
==
0
)
{
return
this
;
}
...
...
src/main/java/emu/grasscutter/netty/
Mihoyo
KcpChannel.java
→
src/main/java/emu/grasscutter/netty/KcpChannel.java
View file @
fa9d703d
...
...
@@ -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 @
fa9d703d
...
...
@@ -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 @
fa9d703d
...
...
@@ -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 @
fa9d703d
...
...
@@ -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 @
fa9d703d
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
));
}
...
...
@@ -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/plugin/api/ServerHook.java
View file @
fa9d703d
package
emu.grasscutter.plugin.api
;
import
emu.grasscutter.game.
Genshin
Player
;
import
emu.grasscutter.game.
player.
Player
;
import
emu.grasscutter.server.game.GameServer
;
import
java.util.LinkedList
;
...
...
@@ -35,7 +35,7 @@ public final class ServerHook {
* Gets all online players.
* @return Players connected to the server.
*/
public
List
<
Genshin
Player
>
getOnlinePlayers
()
{
public
List
<
Player
>
getOnlinePlayers
()
{
return
new
LinkedList
<>(
this
.
server
.
getPlayers
().
values
());
}
}
\ No newline at end of file
src/main/java/emu/grasscutter/server/dispatch/DispatchServer.java
View file @
fa9d703d
...
...
@@ -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
;
...
...
@@ -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 @
fa9d703d
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 @
fa9d703d
...
...
@@ -5,33 +5,33 @@ import java.time.OffsetDateTime;
import
java.util.*
;
import
java.util.concurrent.ConcurrentHashMap
;
import
emu.grasscutter.G
enshin
Constants
;
import
emu.grasscutter.G
ame
Constants
;
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.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
;
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
;
...
...
@@ -82,7 +82,7 @@ public final class GameServer extends MihoyoKcpServer {
return
packetHandler
;
}
public
Map
<
Integer
,
Genshin
Player
>
getPlayers
()
{
public
Map
<
Integer
,
Player
>
getPlayers
()
{
return
players
;
}
...
...
@@ -122,22 +122,22 @@ public final class GameServer extends MihoyoKcpServer {
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
;
...
...
@@ -153,7 +153,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
;
...
...
@@ -163,7 +163,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
();
}
...
...
@@ -204,10 +204,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 @
fa9d703d
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/GameSession.java
View file @
fa9d703d
...
...
@@ -8,11 +8,11 @@ import java.util.Set;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.game.Account
;
import
emu.grasscutter.game.
Genshin
Player
;
import
emu.grasscutter.net.packet.
Genshin
Packet
;
import
emu.grasscutter.game.
player.
Player
;
import
emu.grasscutter.net.packet.
Base
Packet
;
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
;
...
...
@@ -21,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
;
...
...
@@ -67,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
());
...
...
@@ -144,43 +144,35 @@ 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
static
final
Set
<
Integer
>
loopPacket
=
Set
.
of
(
PacketOpcodes
.
PingReq
,
PacketOpcodes
.
PingRsp
,
...
...
@@ -189,10 +181,10 @@ public class GameSession extends MihoyoKcpChannel {
PacketOpcodes
.
QueryPathReq
);
private
void
logPacket
(
GenshinPacket
genshinP
acket
)
{
if
(!
loopPacket
.
contains
(
genshinP
acket
.
getOpcode
()))
{
Grasscutter
.
getLogger
().
info
(
"SEND: "
+
PacketOpcodesUtil
.
getOpcodeName
(
genshinP
acket
.
getOpcode
())
+
" ("
+
genshinP
acket
.
getOpcode
()
+
")"
);
System
.
out
.
println
(
Utils
.
bytesToHex
(
genshinP
acket
.
getData
()));
private
void
logPacket
(
BasePacket
p
acket
)
{
if
(!
loopPacket
.
contains
(
p
acket
.
getOpcode
()))
{
Grasscutter
.
getLogger
().
info
(
"SEND: "
+
PacketOpcodesUtil
.
getOpcodeName
(
p
acket
.
getOpcode
())
+
" ("
+
p
acket
.
getOpcode
()
+
")"
);
System
.
out
.
println
(
Utils
.
bytesToHex
(
p
acket
.
getData
()));
}
}
...
...
src/main/java/emu/grasscutter/server/packet/recv/HandlerAvatarFetterLevelRewardReq.java
View file @
fa9d703d
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/HandlerChangeMailStarNotify.java
0 → 100644
View file @
fa9d703d
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 @
fa9d703d
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
;
...
...
@@ -27,7 +27,7 @@ public class HandlerCombatInvocationsNotify extends PacketHandler {
case
ENTITY_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/HandlerDelMailReq.java
0 → 100644
View file @
fa9d703d
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 @
fa9d703d
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 @
fa9d703d
...
...
@@ -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 @
fa9d703d
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
2
3
4
5
6
7
8
9
10
…
14
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