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
fd1890b0
Commit
fd1890b0
authored
Apr 23, 2022
by
memetrollsXD
Committed by
GitHub
Apr 23, 2022
Browse files
Merge branch 'Grasscutters:development' into development
parents
6dae4d43
cf848779
Changes
44
Show whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/game/TeamManager.java
View file @
fd1890b0
...
...
@@ -8,6 +8,7 @@ import java.util.List;
import
java.util.Map
;
import
java.util.Set
;
import
dev.morphia.annotations.Entity
;
import
dev.morphia.annotations.Transient
;
import
emu.grasscutter.GenshinConstants
;
import
emu.grasscutter.Grasscutter
;
...
...
@@ -41,6 +42,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import
it.unimi.dsi.fastutil.ints.IntOpenHashSet
;
import
it.unimi.dsi.fastutil.ints.IntSet
;
@Entity
public
class
TeamManager
{
@Transient
private
GenshinPlayer
player
;
...
...
src/main/java/emu/grasscutter/game/avatar/AvatarProfileData.java
View file @
fd1890b0
package
emu.grasscutter.game.avatar
;
import
dev.morphia.annotations.Entity
;
@Entity
public
class
AvatarProfileData
{
private
int
avatarId
;
private
int
level
;
...
...
src/main/java/emu/grasscutter/game/avatar/GenshinAvatar.java
View file @
fd1890b0
...
...
@@ -56,7 +56,7 @@ import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import
it.unimi.dsi.fastutil.ints.Int2ObjectMap
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
;
@Entity
(
value
=
"avatars"
,
noClassnameS
tor
ed
=
tru
e
)
@Entity
(
value
=
"avatars"
,
useDiscrimina
tor
=
fals
e
)
public
class
GenshinAvatar
{
@Id
private
ObjectId
id
;
@Indexed
private
int
ownerId
;
// Id of player that this avatar belongs to
...
...
src/main/java/emu/grasscutter/game/friends/Friendship.java
View file @
fd1890b0
...
...
@@ -9,7 +9,7 @@ import emu.grasscutter.net.proto.FriendBriefOuterClass.FriendBrief;
import
emu.grasscutter.net.proto.FriendOnlineStateOuterClass.FriendOnlineState
;
import
emu.grasscutter.net.proto.HeadImageOuterClass.HeadImage
;
@Entity
(
value
=
"friendships"
,
noClassnameS
tor
ed
=
tru
e
)
@Entity
(
value
=
"friendships"
,
useDiscrimina
tor
=
fals
e
)
public
class
Friendship
{
@Id
private
ObjectId
id
;
...
...
src/main/java/emu/grasscutter/game/friends/PlayerProfile.java
View file @
fd1890b0
...
...
@@ -4,6 +4,7 @@ import dev.morphia.annotations.*;
import
emu.grasscutter.game.GenshinPlayer
;
import
emu.grasscutter.utils.Utils
;
@Entity
public
class
PlayerProfile
{
@Transient
private
GenshinPlayer
player
;
...
...
src/main/java/emu/grasscutter/game/gacha/PlayerGachaBannerInfo.java
View file @
fd1890b0
package
emu.grasscutter.game.gacha
;
import
dev.morphia.annotations.Entity
;
@Entity
public
class
PlayerGachaBannerInfo
{
private
int
pity5
=
0
;
private
int
pity4
=
0
;
...
...
src/main/java/emu/grasscutter/game/gacha/PlayerGachaInfo.java
View file @
fd1890b0
package
emu.grasscutter.game.gacha
;
import
dev.morphia.annotations.Entity
;
@Entity
public
class
PlayerGachaInfo
{
private
PlayerGachaBannerInfo
standardBanner
;
private
PlayerGachaBannerInfo
eventCharacterBanner
;
...
...
src/main/java/emu/grasscutter/game/inventory/GenshinItem.java
View file @
fd1890b0
...
...
@@ -34,7 +34,7 @@ import emu.grasscutter.net.proto.SceneWeaponInfoOuterClass.SceneWeaponInfo;
import
emu.grasscutter.net.proto.WeaponOuterClass.Weapon
;
import
emu.grasscutter.utils.WeightedList
;
@Entity
(
value
=
"items"
,
noClassnameS
tor
ed
=
tru
e
)
@Entity
(
value
=
"items"
,
useDiscrimina
tor
=
fals
e
)
public
class
GenshinItem
{
@Id
private
ObjectId
id
;
@Indexed
private
int
ownerId
;
...
...
src/main/java/emu/grasscutter/game/player/PlayerBirthday.java
0 → 100644
View file @
fd1890b0
package
emu.grasscutter.game.player
;
import
dev.morphia.annotations.Entity
;
import
emu.grasscutter.net.proto.BirthdayOuterClass.Birthday
;
@Entity
public
class
PlayerBirthday
{
private
int
day
;
private
int
month
;
public
PlayerBirthday
(){
this
.
day
=
0
;
this
.
month
=
0
;
}
public
PlayerBirthday
(
int
day
,
int
month
){
this
.
day
=
day
;
this
.
month
=
month
;
}
public
PlayerBirthday
set
(
PlayerBirthday
birth
){
this
.
day
=
birth
.
day
;
this
.
month
=
birth
.
month
;
return
this
;
}
public
PlayerBirthday
set
(
int
d
,
int
m
){
this
.
day
=
d
;
this
.
month
=
m
;
return
this
;
}
public
PlayerBirthday
setDay
(
int
value
){
this
.
day
=
value
;
return
this
;
}
public
PlayerBirthday
setMonth
(
int
value
){
this
.
month
=
value
;
return
this
;
}
public
int
getDay
(){
return
this
.
day
;
}
public
int
getMonth
(){
return
this
.
month
;
}
public
Birthday
toProto
(){
return
Birthday
.
newBuilder
()
.
setDay
(
this
.
getDay
())
.
setMonth
(
this
.
getMonth
())
.
build
();
}
public
Birthday
.
Builder
getFilledProtoWhenNotEmpty
(){
if
(
this
.
getDay
()
>
0
)
{
return
Birthday
.
newBuilder
()
.
setDay
(
this
.
getDay
())
.
setMonth
(
this
.
getMonth
());
}
return
Birthday
.
newBuilder
();
}
}
\ No newline at end of file
src/main/java/emu/grasscutter/net/packet/PacketOpcodes.java
View file @
fd1890b0
...
...
@@ -1034,6 +1034,8 @@ public class PacketOpcodes {
public
static
final
int
ShowTemplateReminderNotify
=
3164
;
public
static
final
int
SignInInfoReq
=
2510
;
public
static
final
int
SignInInfoRsp
=
2515
;
public
static
final
int
SitReq
=
354
;
public
static
final
int
SitRsp
=
335
;
public
static
final
int
SocialDataNotify
=
4063
;
public
static
final
int
SpringUseReq
=
1720
;
public
static
final
int
SpringUseRsp
=
1727
;
...
...
@@ -1208,5 +1210,4 @@ public class PacketOpcodes {
public
static
final
int
WorldRoutineChangeNotify
=
3548
;
public
static
final
int
WorldRoutineTypeCloseNotify
=
3513
;
public
static
final
int
WorldRoutineTypeRefreshNotify
=
3545
;
}
\ No newline at end of file
src/main/java/emu/grasscutter/netty/MihoyoKcpServer.java
View file @
fd1890b0
...
...
@@ -64,9 +64,8 @@ public class MihoyoKcpServer extends Thread {
// Wait until the server socket is closed.
f
.
channel
().
closeFuture
().
sync
();
}
catch
(
Exception
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
}
catch
(
Exception
exception
)
{
Grasscutter
.
getLogger
().
error
(
"Unable to start game server."
,
exception
);
}
finally
{
// Close
finish
();
...
...
src/main/java/emu/grasscutter/server/dispatch/DispatchServer.java
View file @
fd1890b0
...
...
@@ -24,6 +24,7 @@ import emu.grasscutter.utils.Utils;
import
javax.net.ssl.KeyManagerFactory
;
import
javax.net.ssl.SSLContext
;
import
java.io.*
;
import
java.net.BindException
;
import
java.net.InetSocketAddress
;
import
java.net.URI
;
import
java.net.URLDecoder
;
...
...
@@ -101,14 +102,14 @@ public final class DispatchServer {
.
setName
(
"os_usa"
)
.
setTitle
(
Grasscutter
.
getConfig
().
getGameServerOptions
().
Name
)
.
setType
(
"DEV_PUBLIC"
)
.
setDispatchUrl
(
"http"
+
(
Grasscutter
.
getConfig
().
getDispatchOptions
().
FrontHTTPS
?
"s"
:
""
)
+
"://"
+
(
Grasscutter
.
getConfig
().
getDispatchOptions
().
PublicIp
.
isEmpty
()
?
Grasscutter
.
getConfig
().
getDispatchOptions
().
Ip
:
Grasscutter
.
getConfig
().
getDispatchOptions
().
PublicIp
)
+
":"
+
getAddress
().
getPort
(
)
+
"/query_cur_region_"
+
defaultServerName
)
.
setDispatchUrl
(
"http"
+
(
Grasscutter
.
getConfig
().
getDispatchOptions
().
FrontHTTPS
?
"s"
:
""
)
+
"://"
+
(
Grasscutter
.
getConfig
().
getDispatchOptions
().
PublicIp
.
isEmpty
()
?
Grasscutter
.
getConfig
().
getDispatchOptions
().
Ip
:
Grasscutter
.
getConfig
().
getDispatchOptions
().
PublicIp
)
+
":"
+
(
Grasscutter
.
getConfig
().
getDispatchOptions
().
PublicPort
!=
0
?
Grasscutter
.
getConfig
().
getDispatchOptions
().
PublicPort
:
Grasscutter
.
getConfig
().
getDispatchOptions
().
Port
)
+
"/query_cur_region_"
+
defaultServerName
)
.
build
();
usedNames
.
add
(
defaultServerName
);
servers
.
add
(
server
);
RegionInfo
serverRegion
=
regionQuery
.
getRegionInfo
().
toBuilder
()
.
setIp
((
Grasscutter
.
getConfig
().
getGameServerOptions
().
PublicIp
.
isEmpty
()
?
Grasscutter
.
getConfig
().
getGameServerOptions
().
Ip
:
Grasscutter
.
getConfig
().
getGameServerOptions
().
PublicIp
))
.
setPort
(
Grasscutter
.
getConfig
().
getGameServerOptions
().
Port
)
.
setPort
(
Grasscutter
.
getConfig
().
getGameServerOptions
().
PublicPort
!=
0
?
Grasscutter
.
getConfig
().
getGameServerOptions
().
PublicPort
:
Grasscutter
.
getConfig
().
getGameServerOptions
().
Port
)
.
setSecretKey
(
ByteString
.
copyFrom
(
FileUtils
.
read
(
Grasscutter
.
getConfig
().
KEY_FOLDER
+
"dispatchSeed.bin"
)))
.
build
();
...
...
@@ -159,11 +160,20 @@ public final class DispatchServer {
}
}
private
HttpServer
safelyCreateServer
(
InetSocketAddress
address
)
{
try
{
return
HttpServer
.
create
(
address
,
0
);
}
catch
(
BindException
ignored
)
{
Grasscutter
.
getLogger
().
error
(
"Unable to bind to port: "
+
getAddress
().
getPort
()
+
" (HTTP)"
);
}
catch
(
Exception
exception
)
{
Grasscutter
.
getLogger
().
error
(
"Unable to start HTTP server."
,
exception
);
}
return
null
;
}
public
void
start
()
throws
Exception
{
HttpServer
server
;
if
(
Grasscutter
.
getConfig
().
getDispatchOptions
().
UseSSL
)
{
HttpsServer
httpsServer
;
httpsServer
=
HttpsServer
.
create
(
getAddress
(),
0
);
HttpsServer
httpsServer
=
HttpsServer
.
create
(
getAddress
(),
0
);
SSLContext
sslContext
=
SSLContext
.
getInstance
(
"TLS"
);
try
(
FileInputStream
fis
=
new
FileInputStream
(
Grasscutter
.
getConfig
().
getDispatchOptions
().
KeystorePath
))
{
char
[]
keystorePassword
=
Grasscutter
.
getConfig
().
getDispatchOptions
().
KeystorePassword
.
toCharArray
();
...
...
@@ -176,15 +186,21 @@ public final class DispatchServer {
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
)
{
Grasscutter
.
getLogger
().
warn
(
"[Dispatch] No SSL cert found! Falling back to HTTP server."
);
Grasscutter
.
getConfig
().
getDispatchOptions
().
UseSSL
=
false
;
server
=
HttpServer
.
create
(
getAddress
()
,
0
);
server
=
this
.
safelyCreateServer
(
this
.
getAddress
());
}
}
else
{
server
=
HttpServer
.
create
(
getAddress
()
,
0
);
server
=
this
.
safelyCreateServer
(
this
.
getAddress
());
}
if
(
server
==
null
)
throw
new
NullPointerException
(
"An HTTP server was not created."
);
server
.
createContext
(
"/"
,
t
->
responseHTML
(
t
,
"Hello"
));
// Dispatch
...
...
src/main/java/emu/grasscutter/server/packet/recv/HandleEvtAvatarSitDownNotify.java
0 → 100644
View file @
fd1890b0
package
emu.grasscutter.server.packet.recv
;
import
emu.grasscutter.net.packet.Opcodes
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.EvtAvatarSitDownNotifyOuterClass.EvtAvatarSitDownNotify
;
import
emu.grasscutter.net.packet.PacketHandler
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.PacketEvtAvatarSitDownNotify
;
@Opcodes
(
PacketOpcodes
.
EvtAvatarSitDownNotify
)
public
class
HandleEvtAvatarSitDownNotify
extends
PacketHandler
{
@Override
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
EvtAvatarSitDownNotify
notify
=
EvtAvatarSitDownNotify
.
parseFrom
(
payload
);
session
.
send
(
new
PacketEvtAvatarSitDownNotify
(
notify
));
}
}
src/main/java/emu/grasscutter/server/packet/recv/HandleSitReq.java
0 → 100644
View file @
fd1890b0
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.SitReqOuterClass
;
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
{
@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
();
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/HandlerSceneEntityDrownReq.java
0 → 100644
View file @
fd1890b0
package
emu.grasscutter.server.packet.recv
;
import
emu.grasscutter.game.entity.GenshinEntity
;
import
emu.grasscutter.game.props.LifeState
;
import
emu.grasscutter.net.packet.Opcodes
;
import
emu.grasscutter.net.packet.PacketHandler
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.SceneEntityDrownReqOuterClass.SceneEntityDrownReq
;
import
emu.grasscutter.net.proto.VisionTypeOuterClass
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify
;
import
emu.grasscutter.server.packet.send.PacketSceneEntityDrownRsp
;
@Opcodes
(
PacketOpcodes
.
SceneEntityDrownReq
)
public
class
HandlerSceneEntityDrownReq
extends
PacketHandler
{
@Override
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
SceneEntityDrownReq
req
=
SceneEntityDrownReq
.
parseFrom
(
payload
);
GenshinEntity
entity
=
session
.
getPlayer
().
getScene
().
getEntityById
(
req
.
getEntityId
());
PacketLifeStateChangeNotify
lifeStateChangeNotify
=
new
PacketLifeStateChangeNotify
(
entity
,
entity
,
LifeState
.
LIFE_DEAD
);
PacketSceneEntityDrownRsp
drownRsp
=
new
PacketSceneEntityDrownRsp
(
req
.
getEntityId
());
//kill entity + broadcast it
session
.
getPlayer
().
getScene
().
broadcastPacket
(
lifeStateChangeNotify
);
session
.
getPlayer
().
getScene
().
broadcastPacket
(
drownRsp
);
//TODO: make a list somewhere of all entities to remove per tick rather than one by one
session
.
getPlayer
().
getScene
().
removeEntity
(
entity
,
VisionTypeOuterClass
.
VisionType
.
VisionDie
);
}
}
src/main/java/emu/grasscutter/server/packet/recv/HandlerSetPlayerBirthdayReq.java
0 → 100644
View file @
fd1890b0
package
emu.grasscutter.server.packet.recv
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.PacketGetPlayerSocialDetailRsp
;
import
emu.grasscutter.server.packet.send.PacketSetPlayerBirthdayRsp
;
import
emu.grasscutter.net.packet.Opcodes
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.packet.PacketHandler
;
import
emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail
;
import
emu.grasscutter.net.proto.SetPlayerBirthdayReqOuterClass.SetPlayerBirthdayReq
;
import
com.google.gson.Gson
;
@Opcodes
(
PacketOpcodes
.
SetPlayerBirthdayReq
)
public
class
HandlerSetPlayerBirthdayReq
extends
PacketHandler
{
@Override
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
SetPlayerBirthdayReq
req
=
SetPlayerBirthdayReq
.
parseFrom
(
payload
);
if
(
req
.
getBirth
()
!=
null
&&
req
.
getBirth
().
getDay
()
>
0
&&
req
.
getBirth
().
getMonth
()
>
0
)
{
int
day
=
req
.
getBirth
().
getDay
();
int
month
=
req
.
getBirth
().
getMonth
();
// Update birthday value
session
.
getPlayer
().
setBirthday
(
day
,
month
);
// Save birthday month and day
session
.
getPlayer
().
save
();
SocialDetail
.
Builder
detail
=
session
.
getPlayer
().
getSocialDetail
();
session
.
send
(
new
PacketSetPlayerBirthdayRsp
(
session
.
getPlayer
()));
session
.
send
(
new
PacketGetPlayerSocialDetailRsp
(
detail
));
}
}
}
src/main/java/emu/grasscutter/server/packet/send/PacketEvtAvatarSitDownNotify.java
0 → 100644
View file @
fd1890b0
package
emu.grasscutter.server.packet.send
;
import
emu.grasscutter.net.packet.GenshinPacket
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.EvtAvatarSitDownNotifyOuterClass.EvtAvatarSitDownNotify
;
public
class
PacketEvtAvatarSitDownNotify
extends
GenshinPacket
{
public
PacketEvtAvatarSitDownNotify
(
EvtAvatarSitDownNotify
notify
)
{
super
(
PacketOpcodes
.
EvtAvatarSitDownNotify
);
EvtAvatarSitDownNotify
proto
=
EvtAvatarSitDownNotify
.
newBuilder
()
.
setEntityId
(
notify
.
getEntityId
())
.
setPosition
(
notify
.
getPosition
())
.
setChairId
(
notify
.
getChairId
())
.
build
();
this
.
setData
(
proto
);
}
}
src/main/java/emu/grasscutter/server/packet/send/PacketPlayerLoginRsp.java
View file @
fd1890b0
...
...
@@ -41,7 +41,7 @@ public class PacketPlayerLoginRsp extends GenshinPacket {
RegionInfo
serverRegion
=
regionQuery
.
getRegionInfo
().
toBuilder
()
.
setIp
((
Grasscutter
.
getConfig
().
getGameServerOptions
().
PublicIp
.
isEmpty
()
?
Grasscutter
.
getConfig
().
getGameServerOptions
().
Ip
:
Grasscutter
.
getConfig
().
getGameServerOptions
().
PublicIp
))
.
setPort
(
Grasscutter
.
getConfig
().
getGameServerOptions
().
Port
)
.
setPort
(
Grasscutter
.
getConfig
().
getGameServerOptions
().
PublicPort
!=
0
?
Grasscutter
.
getConfig
().
getGameServerOptions
().
PublicPort
:
Grasscutter
.
getConfig
().
getGameServerOptions
().
Port
)
.
setSecretKey
(
ByteString
.
copyFrom
(
FileUtils
.
read
(
Grasscutter
.
getConfig
().
KEY_FOLDER
+
"dispatchSeed.bin"
)))
.
build
();
...
...
src/main/java/emu/grasscutter/server/packet/send/PacketSceneEntityDrownRsp.java
0 → 100644
View file @
fd1890b0
package
emu.grasscutter.server.packet.send
;
import
emu.grasscutter.game.entity.GenshinEntity
;
import
emu.grasscutter.net.packet.GenshinPacket
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.SceneEntityDrownRspOuterClass.SceneEntityDrownRsp
;
import
emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType
;
public
class
PacketSceneEntityDrownRsp
extends
GenshinPacket
{
public
PacketSceneEntityDrownRsp
(
int
entityId
)
{
super
(
PacketOpcodes
.
SceneEntityDrownRsp
);
SceneEntityDrownRsp
proto
=
new
SceneEntityDrownRsp
().
toBuilder
().
setEntityId
(
entityId
).
build
();
this
.
setData
(
proto
);
}
}
src/main/java/emu/grasscutter/server/packet/send/PacketSetPlayerBirthdayRsp.java
0 → 100644
View file @
fd1890b0
package
emu.grasscutter.server.packet.send
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.game.GenshinPlayer
;
import
emu.grasscutter.net.packet.GenshinPacket
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.SetPlayerBirthdayRspOuterClass.SetPlayerBirthdayRsp
;
import
emu.grasscutter.net.proto.BirthdayOuterClass.Birthday
;
public
class
PacketSetPlayerBirthdayRsp
extends
GenshinPacket
{
public
PacketSetPlayerBirthdayRsp
(
GenshinPlayer
player
)
{
super
(
PacketOpcodes
.
SetPlayerBirthdayRsp
);
SetPlayerBirthdayRsp
proto
=
SetPlayerBirthdayRsp
.
newBuilder
()
.
setBirth
(
player
.
getBirthday
().
toProto
())
.
build
();
this
.
setData
(
proto
);
}
}
Prev
1
2
3
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