Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
ziqian zhang
Grasscutter
Commits
01b190bc
Commit
01b190bc
authored
May 07, 2022
by
Magix
Committed by
GitHub
May 07, 2022
Browse files
UPGRADE TO 1.1.0 POG
Merge `development` into `stable`
parents
6b81b888
1beddf16
Changes
497
Show whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/game/entity/EntityVehicle.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.game.entity
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.props.EntityIdType
;
import
emu.grasscutter.game.props.PlayerProperty
;
import
emu.grasscutter.game.world.Scene
;
import
emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo
;
import
emu.grasscutter.net.proto.AnimatorParameterValueInfoPairOuterClass.AnimatorParameterValueInfoPair
;
import
emu.grasscutter.net.proto.EntityAuthorityInfoOuterClass.EntityAuthorityInfo
;
import
emu.grasscutter.net.proto.EntityRendererChangedInfoOuterClass.EntityRendererChangedInfo
;
import
emu.grasscutter.net.proto.FightPropPairOuterClass.*
;
import
emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo
;
import
emu.grasscutter.net.proto.PropPairOuterClass.PropPair
;
import
emu.grasscutter.net.proto.ProtEntityTypeOuterClass.ProtEntityType
;
import
emu.grasscutter.net.proto.SceneEntityAiInfoOuterClass.SceneEntityAiInfo
;
import
emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo
;
import
emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo
;
import
emu.grasscutter.net.proto.VectorOuterClass.Vector
;
import
emu.grasscutter.net.proto.VehicleInfoOuterClass.*
;
import
emu.grasscutter.net.proto.VehicleMemberOuterClass.*
;
import
emu.grasscutter.utils.Position
;
import
emu.grasscutter.utils.ProtoHelper
;
import
it.unimi.dsi.fastutil.ints.Int2FloatMap
;
import
it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap
;
import
java.util.List
;
import
java.util.ArrayList
;
public
class
EntityVehicle
extends
EntityBaseGadget
{
private
final
Player
owner
;
private
final
Int2FloatOpenHashMap
fightProp
;
private
final
Position
pos
;
private
final
Position
rot
;
private
final
int
pointId
;
private
final
int
gadgetId
;
private
float
curStamina
;
private
List
<
VehicleMember
>
vehicleMembers
;
public
EntityVehicle
(
Scene
scene
,
Player
player
,
int
gadgetId
,
int
pointId
,
Position
pos
,
Position
rot
)
{
super
(
scene
);
this
.
owner
=
player
;
this
.
id
=
getScene
().
getWorld
().
getNextEntityId
(
EntityIdType
.
GADGET
);
this
.
fightProp
=
new
Int2FloatOpenHashMap
();
this
.
pos
=
new
Position
(
pos
);
this
.
rot
=
new
Position
(
rot
);
this
.
gadgetId
=
gadgetId
;
this
.
pointId
=
pointId
;
this
.
curStamina
=
240
;
this
.
vehicleMembers
=
new
ArrayList
<
VehicleMember
>();
}
@Override
public
int
getGadgetId
()
{
return
gadgetId
;
}
public
Player
getOwner
()
{
return
owner
;
}
public
float
getCurStamina
()
{
return
curStamina
;
}
public
void
setCurStamina
(
float
stamina
)
{
this
.
curStamina
=
stamina
;
}
public
int
getPointId
()
{
return
pointId
;
}
public
List
<
VehicleMember
>
getVehicleMembers
()
{
return
vehicleMembers
;
}
@Override
public
Int2FloatOpenHashMap
getFightProperties
()
{
return
fightProp
;
}
@Override
public
Position
getPosition
()
{
return
this
.
pos
;
}
@Override
public
Position
getRotation
()
{
return
this
.
rot
;
}
@Override
public
SceneEntityInfo
toProto
()
{
VehicleInfo
vehicle
=
VehicleInfo
.
newBuilder
()
.
setOwnerUid
(
this
.
owner
.
getUid
())
.
setCurStamina
(
getCurStamina
())
.
build
();
EntityAuthorityInfo
authority
=
EntityAuthorityInfo
.
newBuilder
()
.
setAbilityInfo
(
AbilitySyncStateInfo
.
newBuilder
())
.
setRendererChangedInfo
(
EntityRendererChangedInfo
.
newBuilder
())
.
setAiInfo
(
SceneEntityAiInfo
.
newBuilder
().
setIsAiOpen
(
true
).
setBornPos
(
getPosition
().
toProto
()))
.
setBornPos
(
getPosition
().
toProto
())
.
build
();
SceneGadgetInfo
.
Builder
gadgetInfo
=
SceneGadgetInfo
.
newBuilder
()
.
setGadgetId
(
this
.
getGadgetId
())
.
setAuthorityPeerId
(
this
.
getOwner
().
getPeerId
())
.
setIsEnableInteract
(
true
)
.
setVehicleInfo
(
vehicle
);
SceneEntityInfo
.
Builder
entityInfo
=
SceneEntityInfo
.
newBuilder
()
.
setEntityId
(
getId
())
.
setEntityType
(
ProtEntityType
.
PROT_ENTITY_GADGET
)
.
setMotionInfo
(
MotionInfo
.
newBuilder
().
setPos
(
getPosition
().
toProto
()).
setRot
(
getRotation
().
toProto
()).
setSpeed
(
Vector
.
newBuilder
()))
.
addAnimatorParaList
(
AnimatorParameterValueInfoPair
.
newBuilder
())
.
setGadget
(
gadgetInfo
)
.
setEntityAuthorityInfo
(
authority
)
.
setLifeState
(
1
);
PropPair
pair
=
PropPair
.
newBuilder
()
.
setType
(
PlayerProperty
.
PROP_LEVEL
.
getId
())
.
setPropValue
(
ProtoHelper
.
newPropValue
(
PlayerProperty
.
PROP_LEVEL
,
47
))
.
build
();
for
(
Int2FloatMap
.
Entry
entry
:
getFightProperties
().
int2FloatEntrySet
())
{
if
(
entry
.
getIntKey
()
==
0
)
{
continue
;
}
FightPropPair
fightProp
=
FightPropPair
.
newBuilder
().
setPropType
(
entry
.
getIntKey
()).
setPropValue
(
entry
.
getFloatValue
()).
build
();
entityInfo
.
addFightPropList
(
fightProp
);
}
entityInfo
.
addPropList
(
pair
);
return
entityInfo
.
build
();
}
}
src/main/java/emu/grasscutter/game/entity/G
enshin
Entity.java
→
src/main/java/emu/grasscutter/game/entity/G
ame
Entity.java
View file @
01b190bc
package
emu.grasscutter.game.entity
;
import
emu.grasscutter.game.GenshinScene
;
import
emu.grasscutter.game.World
;
import
emu.grasscutter.game.props.FightProperty
;
import
emu.grasscutter.game.props.LifeState
;
import
emu.grasscutter.game.world.Scene
;
import
emu.grasscutter.game.world.SpawnDataEntry
;
import
emu.grasscutter.game.world.World
;
import
emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo
;
import
emu.grasscutter.net.proto.MotionStateOuterClass.MotionState
;
import
emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo
;
...
...
@@ -11,28 +12,37 @@ import emu.grasscutter.net.proto.VectorOuterClass.Vector;
import
emu.grasscutter.utils.Position
;
import
it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap
;
public
abstract
class
G
enshin
Entity
{
public
abstract
class
G
ame
Entity
{
protected
int
id
;
private
final
GenshinScene
scene
;
private
final
Scene
scene
;
private
SpawnDataEntry
spawnEntry
;
private
int
blockId
;
private
int
configId
;
private
int
groupId
;
private
MotionState
moveState
;
private
int
lastMoveSceneTimeMs
;
private
int
lastMoveReliableSeq
;
public
G
enshin
Entity
(
Genshin
Scene
scene
)
{
public
G
ame
Entity
(
Scene
scene
)
{
this
.
scene
=
scene
;
this
.
moveState
=
MotionState
.
M
otionNone
;
this
.
moveState
=
MotionState
.
M
OTION_NONE
;
}
public
int
getId
()
{
return
this
.
id
;
}
public
int
getEntityType
()
{
return
getId
()
>>
24
;
}
public
World
getWorld
()
{
return
this
.
getScene
().
getWorld
();
}
public
Genshin
Scene
getScene
()
{
public
Scene
getScene
()
{
return
this
.
scene
;
}
...
...
@@ -94,6 +104,30 @@ public abstract class GenshinEntity {
return
getFightProperties
().
getOrDefault
(
prop
.
getId
(),
0
f
);
}
public
int
getBlockId
()
{
return
blockId
;
}
public
void
setBlockId
(
int
blockId
)
{
this
.
blockId
=
blockId
;
}
public
int
getConfigId
()
{
return
configId
;
}
public
void
setConfigId
(
int
configId
)
{
this
.
configId
=
configId
;
}
public
int
getGroupId
()
{
return
groupId
;
}
public
void
setGroupId
(
int
groupId
)
{
this
.
groupId
=
groupId
;
}
protected
MotionInfo
getMotionInfo
()
{
MotionInfo
proto
=
MotionInfo
.
newBuilder
()
.
setPos
(
getPosition
().
toProto
())
...
...
@@ -104,4 +138,12 @@ public abstract class GenshinEntity {
return
proto
;
}
public
SpawnDataEntry
getSpawnEntry
()
{
return
spawnEntry
;
}
public
void
setSpawnEntry
(
SpawnDataEntry
spawnEntry
)
{
this
.
spawnEntry
=
spawnEntry
;
}
}
src/main/java/emu/grasscutter/game/expedition/ExpeditionInfo.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.game.expedition
;
import
dev.morphia.annotations.Entity
;
@Entity
public
class
ExpeditionInfo
{
public
int
getState
()
{
return
state
;
}
public
void
setState
(
int
state
)
{
this
.
state
=
state
;
}
public
int
getExpId
()
{
return
expId
;
}
public
void
setExpId
(
int
expId
)
{
this
.
expId
=
expId
;
}
public
int
getHourTime
()
{
return
hourTime
;
}
public
void
setHourTime
(
int
hourTime
)
{
this
.
hourTime
=
hourTime
;
}
public
int
getStartTime
()
{
return
startTime
;
}
public
void
setStartTime
(
int
startTime
)
{
this
.
startTime
=
startTime
;
}
private
int
state
;
private
int
expId
;
private
int
hourTime
;
private
int
startTime
;
}
src/main/java/emu/grasscutter/game/expedition/ExpeditionManager.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.game.expedition
;
import
com.google.gson.reflect.TypeToken
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.server.game.GameServer
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectMap
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
;
import
java.io.FileReader
;
import
java.util.Collection
;
import
java.util.List
;
public
class
ExpeditionManager
{
public
GameServer
getGameServer
()
{
return
gameServer
;
}
private
final
GameServer
gameServer
;
public
Int2ObjectMap
<
List
<
ExpeditionRewardDataList
>>
getExpeditionRewardDataList
()
{
return
expeditionRewardData
;
}
private
final
Int2ObjectMap
<
List
<
ExpeditionRewardDataList
>>
expeditionRewardData
;
public
ExpeditionManager
(
GameServer
gameServer
)
{
this
.
gameServer
=
gameServer
;
this
.
expeditionRewardData
=
new
Int2ObjectOpenHashMap
<>();
this
.
load
();
}
public
synchronized
void
load
()
{
try
(
FileReader
fileReader
=
new
FileReader
(
Grasscutter
.
getConfig
().
DATA_FOLDER
+
"ExpeditionReward.json"
))
{
getExpeditionRewardDataList
().
clear
();
List
<
ExpeditionRewardInfo
>
banners
=
Grasscutter
.
getGsonFactory
().
fromJson
(
fileReader
,
TypeToken
.
getParameterized
(
Collection
.
class
,
ExpeditionRewardInfo
.
class
).
getType
());
if
(
banners
.
size
()
>
0
)
{
for
(
ExpeditionRewardInfo
di
:
banners
)
{
getExpeditionRewardDataList
().
put
(
di
.
getExpId
(),
di
.
getExpeditionRewardDataList
());
}
Grasscutter
.
getLogger
().
info
(
"Expedition reward successfully loaded."
);
}
else
{
Grasscutter
.
getLogger
().
error
(
"Unable to load expedition reward. Expedition reward size is 0."
);
}
}
catch
(
Exception
e
)
{
Grasscutter
.
getLogger
().
error
(
"Unable to load expedition reward."
,
e
);
}
}
}
src/main/java/emu/grasscutter/game/expedition/ExpeditionRewardData.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.game.expedition
;
public
class
ExpeditionRewardData
{
private
int
itemId
;
private
int
minCount
;
private
int
maxCount
;
public
int
getItemId
()
{
return
itemId
;
}
public
int
getMinCount
()
{
return
minCount
;
}
public
int
getMaxCount
()
{
return
maxCount
;
}
}
src/main/java/emu/grasscutter/game/expedition/ExpeditionRewardDataList.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.game.expedition
;
import
java.util.List
;
public
class
ExpeditionRewardDataList
{
public
int
getHourTime
()
{
return
hourTime
;
}
public
List
<
ExpeditionRewardData
>
getExpeditionRewardData
()
{
return
expeditionRewardData
;
}
private
int
hourTime
;
private
List
<
ExpeditionRewardData
>
expeditionRewardData
;
}
src/main/java/emu/grasscutter/game/expedition/ExpeditionRewardInfo.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.game.expedition
;
import
java.util.List
;
public
class
ExpeditionRewardInfo
{
public
int
getExpId
()
{
return
expId
;
}
public
List
<
ExpeditionRewardDataList
>
getExpeditionRewardDataList
()
{
return
expeditionRewardDataList
;
}
private
int
expId
;
private
List
<
ExpeditionRewardDataList
>
expeditionRewardDataList
;
}
src/main/java/emu/grasscutter/game/friends/FriendsList.java
View file @
01b190bc
...
...
@@ -3,7 +3,7 @@ package emu.grasscutter.game.friends;
import
java.util.List
;
import
emu.grasscutter.database.DatabaseHelper
;
import
emu.grasscutter.game.
Genshin
Player
;
import
emu.grasscutter.game.
player.
Player
;
import
emu.grasscutter.net.proto.DealAddFriendResultTypeOuterClass.DealAddFriendResultType
;
import
emu.grasscutter.server.packet.send.PacketAskAddFriendNotify
;
import
emu.grasscutter.server.packet.send.PacketAskAddFriendRsp
;
...
...
@@ -14,20 +14,20 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import
it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
;
public
class
FriendsList
{
private
final
Genshin
Player
player
;
private
final
Player
player
;
private
final
Int2ObjectMap
<
Friendship
>
friends
;
private
final
Int2ObjectMap
<
Friendship
>
pendingFriends
;
private
boolean
loaded
=
false
;
public
FriendsList
(
Genshin
Player
player
)
{
public
FriendsList
(
Player
player
)
{
this
.
player
=
player
;
this
.
friends
=
new
Int2ObjectOpenHashMap
<
Friendship
>();
this
.
pendingFriends
=
new
Int2ObjectOpenHashMap
<
Friendship
>();
}
public
Genshin
Player
getPlayer
()
{
public
Player
getPlayer
()
{
return
player
;
}
...
...
@@ -83,7 +83,7 @@ public class FriendsList {
return
;
}
Genshin
Player
target
=
getPlayer
().
getSession
().
getServer
().
getPlayerByUid
(
targetUid
,
true
);
Player
target
=
getPlayer
().
getSession
().
getServer
().
getPlayerByUid
(
targetUid
,
true
);
if
(
target
==
null
)
{
return
;
// Should never happen
}
...
...
@@ -104,7 +104,7 @@ public class FriendsList {
}
// Handle
if
(
result
==
DealAddFriendResultType
.
D
ealAddFriendAccept
)
{
// Request accepted
if
(
result
==
DealAddFriendResultType
.
D
EAL_ADD_FRIEND_ACCEPT
)
{
// Request accepted
myFriendship
.
setIsFriend
(
true
);
theirFriendship
.
setIsFriend
(
true
);
...
...
@@ -143,7 +143,7 @@ public class FriendsList {
myFriendship
.
delete
();
Friendship
theirFriendship
=
null
;
Genshin
Player
friend
=
myFriendship
.
getFriendProfile
().
getPlayer
();
Player
friend
=
myFriendship
.
getFriendProfile
().
getPlayer
();
if
(
friend
!=
null
)
{
// Friend online
theirFriendship
=
friend
.
getFriendsList
().
getFriendById
(
this
.
getPlayer
().
getUid
());
...
...
@@ -165,7 +165,7 @@ public class FriendsList {
}
public
synchronized
void
sendFriendRequest
(
int
targetUid
)
{
Genshin
Player
target
=
getPlayer
().
getSession
().
getServer
().
getPlayerByUid
(
targetUid
,
true
);
Player
target
=
getPlayer
().
getSession
().
getServer
().
getPlayerByUid
(
targetUid
,
true
);
if
(
target
==
null
||
target
==
this
.
getPlayer
())
{
return
;
...
...
@@ -220,7 +220,7 @@ public class FriendsList {
friendship
.
setOwner
(
getPlayer
());
// Check if friend is online
Genshin
Player
friend
=
getPlayer
().
getSession
().
getServer
().
getPlayerByUid
(
friendship
.
getFriendProfile
().
getUid
());
Player
friend
=
getPlayer
().
getSession
().
getServer
().
getPlayerByUid
(
friendship
.
getFriendProfile
().
getUid
());
if
(
friend
!=
null
)
{
// Set friend to online mode
friendship
.
setFriendProfile
(
friend
);
...
...
src/main/java/emu/grasscutter/game/friends/Friendship.java
View file @
01b190bc
package
emu.grasscutter.game.friends
;
import
emu.grasscutter.net.proto.PlatformTypeOuterClass
;
import
org.bson.types.ObjectId
;
import
dev.morphia.annotations.*
;
import
emu.grasscutter.database.DatabaseHelper
;
import
emu.grasscutter.game.
Genshin
Player
;
import
emu.grasscutter.game.
player.
Player
;
import
emu.grasscutter.net.proto.FriendBriefOuterClass.FriendBrief
;
import
emu.grasscutter.net.proto.FriendOnlineStateOuterClass.FriendOnlineState
;
import
emu.grasscutter.net.proto.
HeadImageOuterClass.HeadImag
e
;
import
emu.grasscutter.net.proto.
ProfilePictureOuterClass.ProfilePictur
e
;
@Entity
(
value
=
"friendships"
,
noClassnameS
tor
ed
=
tru
e
)
@Entity
(
value
=
"friendships"
,
useDiscrimina
tor
=
fals
e
)
public
class
Friendship
{
@Id
private
ObjectId
id
;
@Transient
private
Genshin
Player
owner
;
@Transient
private
Player
owner
;
@Indexed
private
int
ownerId
;
@Indexed
private
int
friendId
;
...
...
@@ -25,7 +26,7 @@ public class Friendship {
@Deprecated
// Morphia use only
public
Friendship
()
{
}
public
Friendship
(
Genshin
Player
owner
,
Genshin
Player
friend
,
Genshin
Player
asker
)
{
public
Friendship
(
Player
owner
,
Player
friend
,
Player
asker
)
{
this
.
setOwner
(
owner
);
this
.
ownerId
=
owner
.
getUid
();
this
.
friendId
=
friend
.
getUid
();
...
...
@@ -33,11 +34,11 @@ public class Friendship {
this
.
askerId
=
asker
.
getUid
();
}
public
Genshin
Player
getOwner
()
{
public
Player
getOwner
()
{
return
owner
;
}
public
void
setOwner
(
Genshin
Player
owner
)
{
public
void
setOwner
(
Player
owner
)
{
this
.
owner
=
owner
;
}
...
...
@@ -69,7 +70,7 @@ public class Friendship {
return
profile
;
}
public
void
setFriendProfile
(
Genshin
Player
character
)
{
public
void
setFriendProfile
(
Player
character
)
{
if
(
character
==
null
||
this
.
friendId
!=
character
.
getUid
())
return
;
this
.
profile
=
character
.
getProfile
();
}
...
...
@@ -91,16 +92,16 @@ public class Friendship {
.
setUid
(
getFriendProfile
().
getUid
())
.
setNickname
(
getFriendProfile
().
getName
())
.
setLevel
(
getFriendProfile
().
getPlayerLevel
())
.
set
Avatar
(
HeadImag
e
.
newBuilder
().
setAvatarId
(
getFriendProfile
().
getAvatarId
()))
.
set
ProfilePicture
(
ProfilePictur
e
.
newBuilder
().
setAvatarId
(
getFriendProfile
().
getAvatarId
()))
.
setWorldLevel
(
getFriendProfile
().
getWorldLevel
())
.
setSignature
(
getFriendProfile
().
getSignature
())
.
setOnlineState
(
getFriendProfile
().
isOnline
()
?
FriendOnlineState
.
FRIEND_ONLINE
:
FriendOnlineState
.
FRIEND_DISCONNECT
)
.
setOnlineState
(
getFriendProfile
().
isOnline
()
?
FriendOnlineState
.
FRIEND_ONLINE
:
FriendOnlineState
.
FR
E
IEND_DISCONNECT
)
.
setIsMpModeAvailable
(
true
)
.
setLastActiveTime
(
getFriendProfile
().
getLastActiveTime
())
.
setNameCardId
(
getFriendProfile
().
getNameCard
())
.
setParam
(
getFriendProfile
().
getDaysSinceLogin
())
.
set
Unk1
(
1
)
.
set
Unk2
(
3
)
.
set
IsGameSource
(
true
)
.
set
PlatformType
(
PlatformTypeOuterClass
.
PlatformType
.
PC
)
.
build
();
return
proto
;
...
...
src/main/java/emu/grasscutter/game/friends/PlayerProfile.java
View file @
01b190bc
package
emu.grasscutter.game.friends
;
import
dev.morphia.annotations.*
;
import
emu.grasscutter.game.
Genshin
Player
;
import
emu.grasscutter.game.
player.
Player
;
import
emu.grasscutter.utils.Utils
;
@Entity
public
class
PlayerProfile
{
@Transient
private
Genshin
Player
player
;
@Transient
private
Player
player
;
@AlsoLoad
(
"id"
)
private
int
uid
;
private
int
nameCard
;
...
...
@@ -21,7 +22,7 @@ public class PlayerProfile {
@Deprecated
// Morphia only
public
PlayerProfile
()
{
}
public
PlayerProfile
(
Genshin
Player
player
)
{
public
PlayerProfile
(
Player
player
)
{
this
.
uid
=
player
.
getUid
();
this
.
syncWithCharacter
(
player
);
}
...
...
@@ -30,11 +31,11 @@ public class PlayerProfile {
return
uid
;
}
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
;
}
...
...
@@ -82,7 +83,7 @@ public class PlayerProfile {
return
this
.
getPlayer
()
!=
null
;
}
public
void
syncWithCharacter
(
Genshin
Player
player
)
{
public
void
syncWithCharacter
(
Player
player
)
{
if
(
player
==
null
)
{
return
;
}
...
...
src/main/java/emu/grasscutter/game/gacha/GachaBanner.java
View file @
01b190bc
...
...
@@ -16,8 +16,8 @@ public class GachaBanner {
private
int
sortId
;
private
int
[]
rateUpItems1
;
private
int
[]
rateUpItems2
;
private
int
minItemType
=
1
;
private
int
maxItemType
=
2
;
private
int
baseYellowWeight
=
60
;
// Max 10000
private
int
basePurpleWeight
=
510
;
// Max 10000
private
int
eventChance
=
50
;
// Chance to win a featured event item
private
int
softPity
=
75
;
private
int
hardPity
=
90
;
...
...
@@ -63,20 +63,20 @@ public class GachaBanner {
return
sortId
;
}
public
int
[]
get
RateUpItems1
()
{
return
rateUpItems1
;
public
int
get
BaseYellowWeight
()
{
return
baseYellowWeight
;
}
public
int
[]
get
RateUpItems2
()
{
return
rateUpItems2
;
public
int
get
BasePurpleWeight
()
{
return
basePurpleWeight
;
}
public
int
get
MinItemType
()
{
return
minItemType
;
public
int
[]
get
RateUpItems1
()
{
return
rateUpItems1
;
}
public
int
get
MaxItemType
()
{
return
maxItemType
;
public
int
[]
get
RateUpItems2
()
{
return
rateUpItems2
;
}
public
int
getSoftPity
()
{
...
...
@@ -91,9 +91,21 @@ public class GachaBanner {
return
eventChance
;
}
@Deprecated
public
GachaInfo
toProto
()
{
String
record
=
"http://"
+
(
Grasscutter
.
getConfig
().
getDispatchOptions
().
PublicIp
.
isEmpty
()
?
Grasscutter
.
getConfig
().
getDispatchOptions
().
Ip
:
Grasscutter
.
getConfig
().
getDispatchOptions
().
PublicIp
)
+
"/gacha"
;
return
toProto
(
""
);
}
public
GachaInfo
toProto
(
String
sessionKey
)
{
String
record
=
"http"
+
(
Grasscutter
.
getConfig
().
getDispatchOptions
().
FrontHTTPS
?
"s"
:
""
)
+
"://"
+
(
Grasscutter
.
getConfig
().
getDispatchOptions
().
PublicIp
.
isEmpty
()
?
Grasscutter
.
getConfig
().
getDispatchOptions
().
Ip
:
Grasscutter
.
getConfig
().
getDispatchOptions
().
PublicIp
)
+
":"
+
Integer
.
toString
(
Grasscutter
.
getConfig
().
getDispatchOptions
().
PublicPort
==
0
?
Grasscutter
.
getConfig
().
getDispatchOptions
().
Port
:
Grasscutter
.
getConfig
().
getDispatchOptions
().
PublicPort
)
+
"/gacha?s="
+
sessionKey
+
"&gachaType="
+
gachaType
;
// Grasscutter.getLogger().info("record = " + record);
GachaInfo
.
Builder
info
=
GachaInfo
.
newBuilder
()
.
setGachaType
(
this
.
getGachaType
())
.
setScheduleId
(
this
.
getScheduleId
())
...
...
src/main/java/emu/grasscutter/game/gacha/GachaManager.java
View file @
01b190bc
...
...
@@ -12,13 +12,15 @@ import com.google.gson.reflect.TypeToken;
import
com.sun.nio.file.SensitivityWatchEventModifier
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.data.G
enshin
Data
;
import
emu.grasscutter.data.G
ame
Data
;
import
emu.grasscutter.data.def.ItemData
;
import
emu.grasscutter.game.GenshinPlayer
;
import
emu.grasscutter.game.avatar.GenshinAvatar
;
import
emu.grasscutter.game.inventory.GenshinItem
;
import
emu.grasscutter.database.DatabaseHelper
;
import
emu.grasscutter.game.avatar.Avatar
;
import
emu.grasscutter.game.gacha.GachaBanner.BannerType
;
import
emu.grasscutter.game.inventory.GameItem
;
import
emu.grasscutter.game.inventory.ItemType
;
import
emu.grasscutter.game.inventory.MaterialType
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.net.proto.GachaItemOuterClass.GachaItem
;
import
emu.grasscutter.net.proto.GachaTransferItemOuterClass.GachaTransferItem
;
import
emu.grasscutter.net.proto.GetGachaInfoRspOuterClass.GetGachaInfoRsp
;
...
...
@@ -89,7 +91,7 @@ public class GachaManager {
}
}
public
synchronized
void
doPulls
(
Genshin
Player
player
,
int
gachaType
,
int
times
)
{
public
synchronized
void
doPulls
(
Player
player
,
int
gachaType
,
int
times
)
{
// Sanity check
if
(
times
!=
10
&&
times
!=
1
)
{
return
;
...
...
@@ -108,7 +110,7 @@ public class GachaManager {
// Spend currency
if
(
banner
.
getCostItem
()
>
0
)
{
G
enshin
Item
costItem
=
player
.
getInventory
().
getInventoryTab
(
ItemType
.
ITEM_MATERIAL
).
getItemById
(
banner
.
getCostItem
());
G
ame
Item
costItem
=
player
.
getInventory
().
getInventoryTab
(
ItemType
.
ITEM_MATERIAL
).
getItemById
(
banner
.
getCostItem
());
if
(
costItem
==
null
||
costItem
.
getCount
()
<
times
)
{
return
;
}
...
...
@@ -125,14 +127,14 @@ public class GachaManager {
int
itemId
=
0
;
int
bonusYellowChance
=
gachaInfo
.
getPity5
()
>=
banner
.
getSoftPity
()
?
100
*
(
gachaInfo
.
getPity5
()
-
banner
.
getSoftPity
()
-
1
):
0
;
int
yellowChance
=
60
+
(
int
)
Math
.
floor
(
100
f
*
(
gachaInfo
.
getPity5
()
/
(
banner
.
getSoftPity
()
-
1
D
)))
+
bonusYellowChance
;
int
purpleChance
=
10000
-
(
510
+
(
int
)
Math
.
floor
(
790
f
*
(
gachaInfo
.
getPity4
()
/
8
f
)));
int
yellowChance
=
banner
.
getBaseYellowWeight
()
+
(
int
)
Math
.
floor
(
100
f
*
(
gachaInfo
.
getPity5
()
/
(
banner
.
getSoftPity
()
-
1
D
)))
+
bonusYellowChance
;
int
purpleChance
=
10000
-
(
banner
.
getBasePurpleWeight
()
+
(
int
)
Math
.
floor
(
790
f
*
(
gachaInfo
.
getPity4
()
/
8
f
)));
if
(
random
<=
yellowChance
||
gachaInfo
.
getPity5
()
>=
banner
.
getHardPity
())
{
if
(
banner
.
getRateUpItems1
().
length
>
0
)
{
int
eventChance
=
this
.
randomRange
(
1
,
100
);
if
(
eventChance
>
=
banner
.
getEventChance
()
||
gachaInfo
.
getFailedFeaturedItemPulls
()
>=
1
)
{
if
(
eventChance
<
=
banner
.
getEventChance
()
||
gachaInfo
.
getFailedFeaturedItemPulls
()
>=
1
)
{
itemId
=
getRandom
(
banner
.
getRateUpItems1
());
gachaInfo
.
setFailedFeaturedItemPulls
(
0
);
}
else
{
...
...
@@ -142,7 +144,7 @@ public class GachaManager {
}
if
(
itemId
==
0
)
{
int
typeChance
=
this
.
randomRange
(
banner
.
get
MinItemType
(),
banner
.
getMaxItemType
()
);
int
typeChance
=
this
.
randomRange
(
banner
.
get
BannerType
()
==
BannerType
.
WEAPON
?
2
:
1
,
banner
.
getBannerType
()
==
BannerType
.
EVENT
?
1
:
2
);
if
(
typeChance
==
1
)
{
itemId
=
getRandom
(
this
.
yellowAvatars
);
}
else
{
...
...
@@ -163,7 +165,7 @@ public class GachaManager {
}
if
(
itemId
==
0
)
{
int
typeChance
=
this
.
randomRange
(
banner
.
get
MinItemType
(),
banner
.
getMaxItemType
()
);
int
typeChance
=
this
.
randomRange
(
banner
.
get
BannerType
()
==
BannerType
.
WEAPON
?
2
:
1
,
banner
.
getBannerType
()
==
BannerType
.
EVENT
?
1
:
2
);
if
(
typeChance
==
1
)
{
itemId
=
getRandom
(
this
.
purpleAvatars
);
}
else
{
...
...
@@ -191,11 +193,15 @@ public class GachaManager {
int
stardust
=
0
,
starglitter
=
0
;
for
(
int
itemId
:
wonItems
)
{
ItemData
itemData
=
G
enshin
Data
.
getItemDataMap
().
get
(
itemId
);
ItemData
itemData
=
G
ame
Data
.
getItemDataMap
().
get
(
itemId
);
if
(
itemData
==
null
)
{
continue
;
}
// Write gacha record
GachaRecord
gachaRecord
=
new
GachaRecord
(
itemId
,
player
.
getUid
(),
gachaType
);
DatabaseHelper
.
saveGachaRecord
(
gachaRecord
);
// Create gacha item
GachaItem
.
Builder
gachaItem
=
GachaItem
.
newBuilder
();
int
addStardust
=
0
,
addStarglitter
=
0
;
...
...
@@ -204,11 +210,11 @@ public class GachaManager {
// Const check
if
(
itemData
.
getMaterialType
()
==
MaterialType
.
MATERIAL_AVATAR
)
{
int
avatarId
=
(
itemData
.
getId
()
%
1000
)
+
10000000
;
Genshin
Avatar
avatar
=
player
.
getAvatars
().
getAvatarById
(
avatarId
);
Avatar
avatar
=
player
.
getAvatars
().
getAvatarById
(
avatarId
);
if
(
avatar
!=
null
)
{
int
constLevel
=
avatar
.
getCoreProudSkillLevel
();
int
constItemId
=
itemData
.
getId
()
+
100
;
G
enshin
Item
constItem
=
player
.
getInventory
().
getInventoryTab
(
ItemType
.
ITEM_MATERIAL
).
getItemById
(
constItemId
);
G
ame
Item
constItem
=
player
.
getInventory
().
getInventoryTab
(
ItemType
.
ITEM_MATERIAL
).
getItemById
(
constItemId
);
if
(
constItem
!=
null
)
{
constLevel
+=
constItem
.
getCount
();
}
...
...
@@ -249,7 +255,7 @@ public class GachaManager {
}
// Create item
G
enshin
Item
item
=
new
G
enshin
Item
(
itemData
);
G
ame
Item
item
=
new
G
ame
Item
(
itemData
);
gachaItem
.
setGachaItem
(
item
.
toItemParam
());
player
.
getInventory
().
addItem
(
item
);
...
...
@@ -286,8 +292,6 @@ public class GachaManager {
this
.
watchService
=
FileSystems
.
getDefault
().
newWatchService
();
Path
path
=
new
File
(
Grasscutter
.
getConfig
().
DATA_FOLDER
).
toPath
();
path
.
register
(
watchService
,
new
WatchEvent
.
Kind
[]{
StandardWatchEventKinds
.
ENTRY_MODIFY
},
SensitivityWatchEventModifier
.
HIGH
);
server
.
OnGameServerTick
.
register
(
this
);
}
catch
(
Exception
e
)
{
Grasscutter
.
getLogger
().
error
(
"Unable to load the Gacha Manager Watch Service. If ServerOptions.watchGacha is true it will not auto-reload"
);
e
.
printStackTrace
();
...
...
@@ -322,6 +326,7 @@ public class GachaManager {
}
}
@Deprecated
private
synchronized
GetGachaInfoRsp
createProto
()
{
GetGachaInfoRsp
.
Builder
proto
=
GetGachaInfoRsp
.
newBuilder
().
setGachaRandom
(
12345
);
...
...
@@ -332,11 +337,25 @@ public class GachaManager {
return
proto
.
build
();
}
private
synchronized
GetGachaInfoRsp
createProto
(
String
sessionKey
)
{
GetGachaInfoRsp
.
Builder
proto
=
GetGachaInfoRsp
.
newBuilder
().
setGachaRandom
(
12345
);
for
(
GachaBanner
banner
:
getGachaBanners
().
values
())
{
proto
.
addGachaInfoList
(
banner
.
toProto
(
sessionKey
));
}
return
proto
.
build
();
}
@Deprecated
public
GetGachaInfoRsp
toProto
()
{
if
(
this
.
cachedProto
==
null
)
{
this
.
cachedProto
=
createProto
();
}
return
this
.
cachedProto
;
}
public
GetGachaInfoRsp
toProto
(
String
sessionKey
)
{
return
createProto
(
sessionKey
);
}
}
src/main/java/emu/grasscutter/game/gacha/GachaRecord.java
0 → 100644
View file @
01b190bc
package
emu.grasscutter.game.gacha
;
import
java.util.Date
;
import
org.bson.types.ObjectId
;
import
dev.morphia.annotations.*
;
@Entity
(
value
=
"gachas"
,
useDiscriminator
=
false
)
public
class
GachaRecord
{
@Id
private
ObjectId
id
;
@Indexed
private
int
ownerId
;
private
Date
transactionDate
;
private
int
itemID
;
@Indexed
private
int
gachaType
;
public
GachaRecord
()
{}
public
GachaRecord
(
int
itemId
,
int
ownerId
,
int
gachaType
){
this
.
transactionDate
=
new
Date
();
this
.
itemID
=
itemId
;
this
.
ownerId
=
ownerId
;
this
.
gachaType
=
gachaType
;
}
public
int
getOwnerId
()
{
return
ownerId
;
}
public
void
setOwnerId
(
int
ownerId
)
{
this
.
ownerId
=
ownerId
;
}
public
int
getGachaType
()
{
return
gachaType
;
}
public
void
setGachaType
(
int
type
)
{
this
.
gachaType
=
type
;
}
public
Date
getTransactionDate
()
{
return
transactionDate
;
}
public
void
setTransactionDate
(
Date
transactionDate
)
{
this
.
transactionDate
=
transactionDate
;
}
public
int
getItemID
()
{
return
itemID
;
}
public
void
setItemID
(
int
itemID
)
{
this
.
itemID
=
itemID
;
}
public
ObjectId
getId
(){
return
id
;
}
public
void
setId
(
ObjectId
id
)
{
this
.
id
=
id
;
}
public
String
toString
()
{
return
toJsonString
();
}
public
String
toJsonString
()
{
return
"{\"time\": "
+
this
.
transactionDate
.
getTime
()
+
",\"item\":"
+
this
.
itemID
+
"}"
;
}
}
src/main/java/emu/grasscutter/game/gacha/PlayerGachaBannerInfo.java
View file @
01b190bc
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 @
01b190bc
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/EquipInventoryTab.java
View file @
01b190bc
...
...
@@ -4,26 +4,26 @@ import java.util.HashSet;
import
java.util.Set
;
public
class
EquipInventoryTab
implements
InventoryTab
{
private
final
Set
<
G
enshin
Item
>
items
;
private
final
Set
<
G
ame
Item
>
items
;
private
final
int
maxCapacity
;
public
EquipInventoryTab
(
int
maxCapacity
)
{
this
.
items
=
new
HashSet
<
G
enshin
Item
>();
this
.
items
=
new
HashSet
<
G
ame
Item
>();
this
.
maxCapacity
=
maxCapacity
;
}
@Override
public
G
enshin
Item
getItemById
(
int
id
)
{
public
G
ame
Item
getItemById
(
int
id
)
{
return
null
;
}
@Override
public
void
onAddItem
(
G
enshin
Item
item
)
{
public
void
onAddItem
(
G
ame
Item
item
)
{
this
.
items
.
add
(
item
);
}
@Override
public
void
onRemoveItem
(
G
enshin
Item
item
)
{
public
void
onRemoveItem
(
G
ame
Item
item
)
{
this
.
items
.
remove
(
item
);
}
...
...
src/main/java/emu/grasscutter/game/inventory/G
enshin
Item.java
→
src/main/java/emu/grasscutter/game/inventory/G
ame
Item.java
View file @
01b190bc
...
...
@@ -13,13 +13,13 @@ import dev.morphia.annotations.Indexed;
import
dev.morphia.annotations.PostLoad
;
import
dev.morphia.annotations.Transient
;
import
emu.grasscutter.data.G
enshin
Data
;
import
emu.grasscutter.data.G
enshin
Depot
;
import
emu.grasscutter.data.G
ame
Data
;
import
emu.grasscutter.data.G
ame
Depot
;
import
emu.grasscutter.data.def.ItemData
;
import
emu.grasscutter.data.def.ReliquaryAffixData
;
import
emu.grasscutter.data.def.ReliquaryMainPropData
;
import
emu.grasscutter.database.DatabaseHelper
;
import
emu.grasscutter.game.
Genshin
Player
;
import
emu.grasscutter.game.
player.
Player
;
import
emu.grasscutter.game.props.FightProperty
;
import
emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo
;
import
emu.grasscutter.net.proto.EquipOuterClass.Equip
;
...
...
@@ -34,8 +34,8 @@ 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
)
public
class
G
enshin
Item
{
@Entity
(
value
=
"items"
,
useDiscrimina
tor
=
fals
e
)
public
class
G
ame
Item
{
@Id
private
ObjectId
id
;
@Indexed
private
int
ownerId
;
private
int
itemId
;
...
...
@@ -62,23 +62,23 @@ public class GenshinItem {
private
int
equipCharacter
;
@Transient
private
int
weaponEntityId
;
public
G
enshin
Item
()
{
public
G
ame
Item
()
{
// Morphia only
}
public
G
enshin
Item
(
int
itemId
)
{
this
(
G
enshin
Data
.
getItemDataMap
().
get
(
itemId
));
public
G
ame
Item
(
int
itemId
)
{
this
(
G
ame
Data
.
getItemDataMap
().
get
(
itemId
));
}
public
G
enshin
Item
(
int
itemId
,
int
count
)
{
this
(
G
enshin
Data
.
getItemDataMap
().
get
(
itemId
),
count
);
public
G
ame
Item
(
int
itemId
,
int
count
)
{
this
(
G
ame
Data
.
getItemDataMap
().
get
(
itemId
),
count
);
}
public
G
enshin
Item
(
ItemData
data
)
{
public
G
ame
Item
(
ItemData
data
)
{
this
(
data
,
1
);
}
public
G
enshin
Item
(
ItemData
data
,
int
count
)
{
public
G
ame
Item
(
ItemData
data
,
int
count
)
{
this
.
itemId
=
data
.
getId
();
this
.
itemData
=
data
;
...
...
@@ -90,7 +90,7 @@ public class GenshinItem {
// Equip data
if
(
getItemType
()
==
ItemType
.
ITEM_WEAPON
)
{
this
.
level
=
1
;
this
.
level
=
Math
.
max
(
this
.
count
,
1
)
;
this
.
affixes
=
new
ArrayList
<>(
2
);
if
(
getItemData
().
getSkillAffix
()
!=
null
)
{
for
(
int
skillAffix
:
getItemData
().
getSkillAffix
())
{
...
...
@@ -103,7 +103,7 @@ public class GenshinItem {
this
.
level
=
1
;
this
.
appendPropIdList
=
new
ArrayList
<>();
// Create main property
ReliquaryMainPropData
mainPropData
=
G
enshin
Depot
.
getRandomRelicMainProp
(
getItemData
().
getMainPropDepotId
());
ReliquaryMainPropData
mainPropData
=
G
ame
Depot
.
getRandomRelicMainProp
(
getItemData
().
getMainPropDepotId
());
if
(
mainPropData
!=
null
)
{
this
.
mainPropId
=
mainPropData
.
getId
();
}
...
...
@@ -124,9 +124,9 @@ public class GenshinItem {
return
ownerId
;
}
public
void
setOwner
(
Genshin
Player
player
)
{
public
void
setOwner
(
Player
player
)
{
this
.
ownerId
=
player
.
getUid
();
this
.
guid
=
player
.
getNextG
enshin
Guid
();
this
.
guid
=
player
.
getNextG
ame
Guid
();
}
public
int
getItemId
()
{
return
itemId
;
...
...
@@ -244,6 +244,10 @@ public class GenshinItem {
return
mainPropId
;
}
public
void
setMainPropId
(
int
mainPropId
)
{
this
.
mainPropId
=
mainPropId
;
}
public
List
<
Integer
>
getAppendPropIdList
()
{
return
appendPropIdList
;
}
...
...
@@ -261,7 +265,7 @@ public class GenshinItem {
}
private
void
addNewAppendProp
()
{
List
<
ReliquaryAffixData
>
affixList
=
G
enshin
Depot
.
getRandomRelicAffixList
(
getItemData
().
getAppendPropDepotId
());
List
<
ReliquaryAffixData
>
affixList
=
G
ame
Depot
.
getRandomRelicAffixList
(
getItemData
().
getAppendPropDepotId
());
if
(
affixList
==
null
)
{
return
;
...
...
@@ -269,13 +273,13 @@ public class GenshinItem {
// Build blacklist - Dont add same stat as main/sub stat
Set
<
FightProperty
>
blacklist
=
new
HashSet
<>();
ReliquaryMainPropData
mainPropData
=
G
enshin
Data
.
getReliquaryMainPropDataMap
().
get
(
this
.
getMainPropId
());
ReliquaryMainPropData
mainPropData
=
G
ame
Data
.
getReliquaryMainPropDataMap
().
get
(
this
.
getMainPropId
());
if
(
mainPropData
!=
null
)
{
blacklist
.
add
(
mainPropData
.
getFightProp
());
}
int
len
=
Math
.
min
(
4
,
this
.
getAppendPropIdList
().
size
());
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
ReliquaryAffixData
affixData
=
G
enshin
Data
.
getReliquaryAffixDataMap
().
get
((
int
)
this
.
getAppendPropIdList
().
get
(
i
));
ReliquaryAffixData
affixData
=
G
ame
Data
.
getReliquaryAffixDataMap
().
get
((
int
)
this
.
getAppendPropIdList
().
get
(
i
));
if
(
affixData
!=
null
)
{
blacklist
.
add
(
affixData
.
getFightProp
());
}
...
...
@@ -299,7 +303,7 @@ public class GenshinItem {
}
private
void
upgradeRandomAppendProp
()
{
List
<
ReliquaryAffixData
>
affixList
=
G
enshin
Depot
.
getRandomRelicAffixList
(
getItemData
().
getAppendPropDepotId
());
List
<
ReliquaryAffixData
>
affixList
=
G
ame
Depot
.
getRandomRelicAffixList
(
getItemData
().
getAppendPropDepotId
());
if
(
affixList
==
null
)
{
return
;
...
...
@@ -309,7 +313,7 @@ public class GenshinItem {
Set
<
FightProperty
>
whitelist
=
new
HashSet
<>();
int
len
=
Math
.
min
(
4
,
this
.
getAppendPropIdList
().
size
());
for
(
int
i
=
0
;
i
<
len
;
i
++)
{
ReliquaryAffixData
affixData
=
G
enshin
Data
.
getReliquaryAffixDataMap
().
get
((
int
)
this
.
getAppendPropIdList
().
get
(
i
));
ReliquaryAffixData
affixData
=
G
ame
Data
.
getReliquaryAffixDataMap
().
get
((
int
)
this
.
getAppendPropIdList
().
get
(
i
));
if
(
affixData
!=
null
)
{
whitelist
.
add
(
affixData
.
getFightProp
());
}
...
...
@@ -331,7 +335,7 @@ public class GenshinItem {
@PostLoad
public
void
onLoad
()
{
if
(
this
.
itemData
==
null
)
{
this
.
itemData
=
G
enshin
Data
.
getItemDataMap
().
get
(
getItemId
());
this
.
itemData
=
G
ame
Data
.
getItemDataMap
().
get
(
getItemId
());
}
}
...
...
@@ -371,13 +375,7 @@ public class GenshinItem {
return
relicInfo
;
}
public
Item
toProto
()
{
Item
.
Builder
proto
=
Item
.
newBuilder
()
.
setGuid
(
this
.
getGuid
())
.
setItemId
(
this
.
getItemId
());
switch
(
getItemType
())
{
case
ITEM_WEAPON:
public
Weapon
toWeaponProto
()
{
Weapon
.
Builder
weapon
=
Weapon
.
newBuilder
()
.
setLevel
(
this
.
getLevel
())
.
setExp
(
this
.
getExp
())
...
...
@@ -389,23 +387,33 @@ public class GenshinItem {
}
}
proto
.
setEquip
(
Equip
.
newBuilder
().
setWeapon
(
weapon
).
setIsLocked
(
this
.
isLocked
()).
build
());
break
;
case
ITEM_RELIQUARY:
Reliquary
relic
=
Reliquary
.
newBuilder
()
return
weapon
.
build
();
}
public
Reliquary
toReliquaryProto
()
{
Reliquary
.
Builder
relic
=
Reliquary
.
newBuilder
()
.
setLevel
(
this
.
getLevel
())
.
setExp
(
this
.
getExp
())
.
setPromoteLevel
(
this
.
getPromoteLevel
())
.
setMainPropId
(
this
.
getMainPropId
())
.
addAllAppendPropIdList
(
this
.
getAppendPropIdList
())
.
build
();
proto
.
setEquip
(
Equip
.
newBuilder
().
setReliquary
(
relic
).
setIsLocked
(
this
.
isLocked
()).
build
());
.
addAllAppendPropIdList
(
this
.
getAppendPropIdList
());
return
relic
.
build
();
}
public
Item
toProto
()
{
Item
.
Builder
proto
=
Item
.
newBuilder
()
.
setGuid
(
this
.
getGuid
())
.
setItemId
(
this
.
getItemId
());
switch
(
getItemType
())
{
case
ITEM_WEAPON:
Weapon
weapon
=
this
.
toWeaponProto
();
proto
.
setEquip
(
Equip
.
newBuilder
().
setWeapon
(
weapon
).
setIsLocked
(
this
.
isLocked
()).
build
());
break
;
case
ITEM_MATERIAL:
Material
material
=
Material
.
newBuilder
()
.
setCount
(
getCount
())
.
build
();
proto
.
setMaterial
(
material
);
case
ITEM_RELIQUARY:
Reliquary
relic
=
this
.
toReliquaryProto
();
proto
.
setEquip
(
Equip
.
newBuilder
().
setReliquary
(
relic
).
setIsLocked
(
this
.
isLocked
()).
build
());
break
;
case
ITEM_FURNITURE:
Furniture
furniture
=
Furniture
.
newBuilder
()
...
...
@@ -414,6 +422,10 @@ public class GenshinItem {
proto
.
setFurniture
(
furniture
);
break
;
default
:
Material
material
=
Material
.
newBuilder
()
.
setCount
(
getCount
())
.
build
();
proto
.
setMaterial
(
material
);
break
;
}
...
...
src/main/java/emu/grasscutter/game/inventory/Inventory.java
View file @
01b190bc
...
...
@@ -5,20 +5,22 @@ import java.util.Iterator;
import
java.util.LinkedList
;
import
java.util.List
;
import
emu.grasscutter.G
enshin
Constants
;
import
emu.grasscutter.G
ame
Constants
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.data.G
enshin
Data
;
import
emu.grasscutter.data.G
ame
Data
;
import
emu.grasscutter.data.def.AvatarCostumeData
;
import
emu.grasscutter.data.def.AvatarData
;
import
emu.grasscutter.data.def.AvatarFlycloakData
;
import
emu.grasscutter.data.def.ItemData
;
import
emu.grasscutter.database.DatabaseHelper
;
import
emu.grasscutter.game.GenshinPlayer
;
import
emu.grasscutter.game.avatar.AvatarStorage
;
import
emu.grasscutter.game.avatar.
Genshin
Avatar
;
import
emu.grasscutter.game.avatar.Avatar
;
import
emu.grasscutter.game.entity.EntityAvatar
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.props.ActionReason
;
import
emu.grasscutter.net.proto.ItemParamOuterClass.ItemParam
;
import
emu.grasscutter.server.packet.send.PacketAvatarEquipChangeNotify
;
import
emu.grasscutter.server.packet.send.PacketItemAddHintNotify
;
import
emu.grasscutter.server.packet.send.PacketStoreItemChangeNotify
;
import
emu.grasscutter.server.packet.send.PacketStoreItemDelNotify
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectMap
;
...
...
@@ -26,13 +28,13 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import
it.unimi.dsi.fastutil.longs.Long2ObjectMap
;
import
it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap
;
public
class
Inventory
implements
Iterable
<
G
enshin
Item
>
{
private
final
Genshin
Player
player
;
public
class
Inventory
implements
Iterable
<
G
ame
Item
>
{
private
final
Player
player
;
private
final
Long2ObjectMap
<
G
enshin
Item
>
store
;
private
final
Long2ObjectMap
<
G
ame
Item
>
store
;
private
final
Int2ObjectMap
<
InventoryTab
>
inventoryTypes
;
public
Inventory
(
Genshin
Player
player
)
{
public
Inventory
(
Player
player
)
{
this
.
player
=
player
;
this
.
store
=
new
Long2ObjectOpenHashMap
<>();
this
.
inventoryTypes
=
new
Int2ObjectOpenHashMap
<>();
...
...
@@ -43,7 +45,7 @@ public class Inventory implements Iterable<GenshinItem> {
this
.
createInventoryTab
(
ItemType
.
ITEM_FURNITURE
,
new
MaterialInventoryTab
(
Grasscutter
.
getConfig
().
getGameServerOptions
().
InventoryLimitFurniture
));
}
public
Genshin
Player
getPlayer
()
{
public
Player
getPlayer
()
{
return
player
;
}
...
...
@@ -51,7 +53,7 @@ public class Inventory implements Iterable<GenshinItem> {
return
this
.
getPlayer
().
getAvatars
();
}
public
Long2ObjectMap
<
G
enshin
Item
>
getItems
()
{
public
Long2ObjectMap
<
G
ame
Item
>
getItems
()
{
return
store
;
}
...
...
@@ -67,7 +69,7 @@ public class Inventory implements Iterable<GenshinItem> {
this
.
getInventoryTypes
().
put
(
type
.
getValue
(),
tab
);
}
public
G
enshin
Item
getItemByGuid
(
long
id
)
{
public
G
ame
Item
getItemByGuid
(
long
id
)
{
return
this
.
getItems
().
get
(
id
);
}
...
...
@@ -76,19 +78,19 @@ public class Inventory implements Iterable<GenshinItem> {
}
public
boolean
addItem
(
int
itemId
,
int
count
)
{
ItemData
itemData
=
G
enshin
Data
.
getItemDataMap
().
get
(
itemId
);
ItemData
itemData
=
G
ame
Data
.
getItemDataMap
().
get
(
itemId
);
if
(
itemData
==
null
)
{
return
false
;
}
G
enshin
Item
item
=
new
G
enshin
Item
(
itemData
,
count
);
G
ame
Item
item
=
new
G
ame
Item
(
itemData
,
count
);
return
addItem
(
item
);
}
public
boolean
addItem
(
G
enshin
Item
item
)
{
G
enshin
Item
result
=
putItem
(
item
);
public
boolean
addItem
(
G
ame
Item
item
)
{
G
ame
Item
result
=
putItem
(
item
);
if
(
result
!=
null
)
{
getPlayer
().
sendPacket
(
new
PacketStoreItemChangeNotify
(
result
));
...
...
@@ -98,34 +100,56 @@ public class Inventory implements Iterable<GenshinItem> {
return
false
;
}
public
void
addItem
s
(
Collection
<
GenshinItem
>
items
)
{
List
<
GenshinItem
>
changedItems
=
new
LinkedList
<>(
);
public
boolean
addItem
(
GameItem
item
,
ActionReason
reason
)
{
boolean
result
=
addItem
(
item
);
for
(
GenshinItem
item
:
items
)
{
GenshinItem
result
=
putItem
(
item
);
if
(
result
!=
null
)
{
changedItems
.
add
(
result
);
if
(
result
&&
reason
!=
null
)
{
getPlayer
().
sendPacket
(
new
PacketItemAddHintNotify
(
item
,
reason
));
}
return
result
;
}
getPlayer
().
sendPacket
(
new
PacketStoreItemChangeNotify
(
changedItems
));
public
boolean
addItem
(
GameItem
item
,
ActionReason
reason
,
boolean
forceNotify
)
{
boolean
result
=
addItem
(
item
);
if
(
reason
!=
null
&&
(
forceNotify
||
result
))
{
getPlayer
().
sendPacket
(
new
PacketItemAddHintNotify
(
item
,
reason
));
}
public
void
addItemParams
(
Collection
<
ItemParam
>
items
)
{
List
<
GenshinItem
>
changedItems
=
new
LinkedList
<>();
return
result
;
}
public
void
addItems
(
Collection
<
GameItem
>
items
)
{
this
.
addItems
(
items
,
null
);
}
for
(
ItemParam
itemParam
:
items
)
{
GenshinItem
toAdd
=
new
GenshinItem
(
itemParam
.
getItemId
(),
itemParam
.
getCount
());
GenshinItem
result
=
putItem
(
toAdd
);
public
void
addItems
(
Collection
<
GameItem
>
items
,
ActionReason
reason
)
{
List
<
GameItem
>
changedItems
=
new
LinkedList
<>();
for
(
GameItem
item
:
items
)
{
GameItem
result
=
putItem
(
item
);
if
(
result
!=
null
)
{
changedItems
.
add
(
result
);
}
}
if
(
changedItems
.
size
()
==
0
)
{
return
;
}
if
(
reason
!=
null
)
{
getPlayer
().
sendPacket
(
new
PacketItemAddHintNotify
(
changedItems
,
reason
));
}
getPlayer
().
sendPacket
(
new
PacketStoreItemChangeNotify
(
changedItems
));
}
private
synchronized
GenshinItem
putItem
(
GenshinItem
item
)
{
public
void
addItemParams
(
Collection
<
ItemParam
>
items
)
{
addItems
(
items
.
stream
().
map
(
param
->
new
GameItem
(
param
.
getItemId
(),
param
.
getCount
())).
toList
(),
null
);
}
private
synchronized
GameItem
putItem
(
GameItem
item
)
{
// Dont add items that dont have a valid item definition.
if
(
item
.
getItemData
()
==
null
)
{
return
null
;
...
...
@@ -140,32 +164,35 @@ public class Inventory implements Iterable<GenshinItem> {
if
(
tab
.
getSize
()
>=
tab
.
getMaxCapacity
())
{
return
null
;
}
// Duplicates cause problems
item
.
setCount
(
Math
.
max
(
item
.
getCount
(),
1
));
// Adds to inventory
putItem
(
item
,
tab
);
}
else
if
(
type
==
ItemType
.
ITEM_VIRTUAL
)
{
// Handle
this
.
addVirtualItem
(
item
.
getItemId
(),
item
.
getCount
());
return
null
;
return
item
;
}
else
if
(
item
.
getItemData
().
getMaterialType
()
==
MaterialType
.
MATERIAL_AVATAR
)
{
// Get avatar id
int
avatarId
=
(
item
.
getItemId
()
%
1000
)
+
10000000
;
// Dont let people give themselves extra main characters
if
(
avatarId
==
G
enshin
Constants
.
MAIN_CHARACTER_MALE
||
avatarId
==
G
enshin
Constants
.
MAIN_CHARACTER_FEMALE
)
{
if
(
avatarId
==
G
ame
Constants
.
MAIN_CHARACTER_MALE
||
avatarId
==
G
ame
Constants
.
MAIN_CHARACTER_FEMALE
)
{
return
null
;
}
// Add avatar
AvatarData
avatarData
=
G
enshin
Data
.
getAvatarDataMap
().
get
(
avatarId
);
AvatarData
avatarData
=
G
ame
Data
.
getAvatarDataMap
().
get
(
avatarId
);
if
(
avatarData
!=
null
&&
!
player
.
getAvatars
().
hasAvatar
(
avatarId
))
{
this
.
getPlayer
().
addAvatar
(
new
Genshin
Avatar
(
avatarData
));
this
.
getPlayer
().
addAvatar
(
new
Avatar
(
avatarData
));
}
return
null
;
}
else
if
(
item
.
getItemData
().
getMaterialType
()
==
MaterialType
.
MATERIAL_FLYCLOAK
)
{
AvatarFlycloakData
flycloakData
=
G
enshin
Data
.
getAvatarFlycloakDataMap
().
get
(
item
.
getItemId
());
AvatarFlycloakData
flycloakData
=
G
ame
Data
.
getAvatarFlycloakDataMap
().
get
(
item
.
getItemId
());
if
(
flycloakData
!=
null
&&
!
player
.
getFlyCloakList
().
contains
(
item
.
getItemId
()))
{
getPlayer
().
addFlycloak
(
item
.
getItemId
());
}
return
null
;
}
else
if
(
item
.
getItemData
().
getMaterialType
()
==
MaterialType
.
MATERIAL_COSTUME
)
{
AvatarCostumeData
costumeData
=
G
enshin
Data
.
getAvatarCostumeDataItemIdMap
().
get
(
item
.
getItemId
());
AvatarCostumeData
costumeData
=
G
ame
Data
.
getAvatarCostumeDataItemIdMap
().
get
(
item
.
getItemId
());
if
(
costumeData
!=
null
&&
!
player
.
getCostumeList
().
contains
(
costumeData
.
getId
()))
{
getPlayer
().
addCostume
(
costumeData
.
getId
());
}
...
...
@@ -176,7 +203,7 @@ public class Inventory implements Iterable<GenshinItem> {
}
return
null
;
}
else
if
(
tab
!=
null
)
{
G
enshin
Item
existingItem
=
tab
.
getItemById
(
item
.
getItemId
());
G
ame
Item
existingItem
=
tab
.
getItemById
(
item
.
getItemId
());
if
(
existingItem
==
null
)
{
// Item type didnt exist before, we will add it to main inventory map if there is enough space
if
(
tab
.
getSize
()
>=
tab
.
getMaxCapacity
())
{
...
...
@@ -194,12 +221,13 @@ public class Inventory implements Iterable<GenshinItem> {
}
// Set ownership and save to db
if
(
item
.
getItemData
().
getItemType
()
!=
ItemType
.
ITEM_VIRTUAL
)
item
.
save
();
return
item
;
}
private
synchronized
void
putItem
(
G
enshin
Item
item
,
InventoryTab
tab
)
{
private
synchronized
void
putItem
(
G
ame
Item
item
,
InventoryTab
tab
)
{
// Set owner and guid FIRST!
item
.
setOwner
(
getPlayer
());
// Put in item store
...
...
@@ -212,25 +240,29 @@ public class Inventory implements Iterable<GenshinItem> {
private
void
addVirtualItem
(
int
itemId
,
int
count
)
{
switch
(
itemId
)
{
case
101
:
// Character exp
for
(
EntityAvatar
entity
:
getPlayer
().
getTeamManager
().
getActiveTeam
())
{
getPlayer
().
getServer
().
getInventoryManager
().
upgradeAvatar
(
player
,
entity
.
getAvatar
(),
count
);
}
getPlayer
().
getServer
().
getInventoryManager
().
upgradeAvatar
(
player
,
getPlayer
().
getTeamManager
().
getCurrentAvatarEntity
().
getAvatar
(),
count
);
break
;
case
102
:
// Adventure exp
getPlayer
().
addExpDirectly
(
count
);
break
;
case
105
:
// Companionship exp
getPlayer
().
getServer
().
getInventoryManager
().
upgradeAvatarFetterLevel
(
player
,
getPlayer
().
getTeamManager
().
getCurrentAvatarEntity
().
getAvatar
(),
count
);
break
;
case
201
:
// Primogem
getPlayer
().
setPrimogems
(
player
.
getPrimogems
()
+
count
);
break
;
case
202
:
// Mora
getPlayer
().
setMora
(
player
.
getMora
()
+
count
);
break
;
case
203
:
// Genesis Crystals
getPlayer
().
setCrystals
(
player
.
getCrystals
()
+
count
);
break
;
}
}
public
void
removeItems
(
List
<
G
enshin
Item
>
items
)
{
public
void
removeItems
(
List
<
G
ame
Item
>
items
)
{
// TODO Bulk delete
for
(
G
enshin
Item
item
:
items
)
{
for
(
G
ame
Item
item
:
items
)
{
this
.
removeItem
(
item
,
item
.
getCount
());
}
}
...
...
@@ -240,7 +272,7 @@ public class Inventory implements Iterable<GenshinItem> {
}
public
synchronized
boolean
removeItem
(
long
guid
,
int
count
)
{
G
enshin
Item
item
=
this
.
getItemByGuid
(
guid
);
G
ame
Item
item
=
this
.
getItemByGuid
(
guid
);
if
(
item
==
null
)
{
return
false
;
...
...
@@ -249,17 +281,21 @@ public class Inventory implements Iterable<GenshinItem> {
return
removeItem
(
item
,
count
);
}
public
synchronized
boolean
removeItem
(
G
enshin
Item
item
)
{
public
synchronized
boolean
removeItem
(
G
ame
Item
item
)
{
return
removeItem
(
item
,
item
.
getCount
());
}
public
synchronized
boolean
removeItem
(
G
enshin
Item
item
,
int
count
)
{
public
synchronized
boolean
removeItem
(
G
ame
Item
item
,
int
count
)
{
// Sanity check
if
(
count
<=
0
||
item
==
null
)
{
return
false
;
}
if
(
item
.
getItemData
().
isEquip
())
{
item
.
setCount
(
0
);
}
else
{
item
.
setCount
(
item
.
getCount
()
-
count
);
}
if
(
item
.
getCount
()
<=
0
)
{
// Remove from inventory tab too
...
...
@@ -282,7 +318,7 @@ public class Inventory implements Iterable<GenshinItem> {
return
true
;
}
private
void
deleteItem
(
G
enshin
Item
item
,
InventoryTab
tab
)
{
private
void
deleteItem
(
G
ame
Item
item
,
InventoryTab
tab
)
{
getItems
().
remove
(
item
.
getGuid
());
if
(
tab
!=
null
)
{
tab
.
onRemoveItem
(
item
);
...
...
@@ -290,8 +326,8 @@ public class Inventory implements Iterable<GenshinItem> {
}
public
boolean
equipItem
(
long
avatarGuid
,
long
equipGuid
)
{
Genshin
Avatar
avatar
=
getPlayer
().
getAvatars
().
getAvatarByGuid
(
avatarGuid
);
G
enshin
Item
item
=
this
.
getItemByGuid
(
equipGuid
);
Avatar
avatar
=
getPlayer
().
getAvatars
().
getAvatarByGuid
(
avatarGuid
);
G
ame
Item
item
=
this
.
getItemByGuid
(
equipGuid
);
if
(
avatar
!=
null
&&
item
!=
null
)
{
return
avatar
.
equipItem
(
item
,
true
);
...
...
@@ -301,7 +337,7 @@ public class Inventory implements Iterable<GenshinItem> {
}
public
boolean
unequipItem
(
long
avatarGuid
,
int
slot
)
{
Genshin
Avatar
avatar
=
getPlayer
().
getAvatars
().
getAvatarByGuid
(
avatarGuid
);
Avatar
avatar
=
getPlayer
().
getAvatars
().
getAvatarByGuid
(
avatarGuid
);
EquipType
equipType
=
EquipType
.
getTypeByValue
(
slot
);
if
(
avatar
!=
null
&&
equipType
!=
EquipType
.
EQUIP_WEAPON
)
{
...
...
@@ -316,15 +352,15 @@ public class Inventory implements Iterable<GenshinItem> {
}
public
void
loadFromDatabase
()
{
List
<
G
enshin
Item
>
items
=
DatabaseHelper
.
getInventoryItems
(
getPlayer
());
List
<
G
ame
Item
>
items
=
DatabaseHelper
.
getInventoryItems
(
getPlayer
());
for
(
G
enshin
Item
item
:
items
)
{
for
(
G
ame
Item
item
:
items
)
{
// Should never happen
if
(
item
.
getObjectId
()
==
null
)
{
continue
;
}
ItemData
itemData
=
G
enshin
Data
.
getItemDataMap
().
get
(
item
.
getItemId
());
ItemData
itemData
=
G
ame
Data
.
getItemDataMap
().
get
(
item
.
getItemId
());
if
(
itemData
==
null
)
{
continue
;
}
...
...
@@ -340,7 +376,7 @@ public class Inventory implements Iterable<GenshinItem> {
// Equip to a character if possible
if
(
item
.
isEquipped
())
{
Genshin
Avatar
avatar
=
getPlayer
().
getAvatars
().
getAvatarById
(
item
.
getEquipCharacter
());
Avatar
avatar
=
getPlayer
().
getAvatars
().
getAvatarById
(
item
.
getEquipCharacter
());
boolean
hasEquipped
=
false
;
if
(
avatar
!=
null
)
{
...
...
@@ -356,7 +392,7 @@ public class Inventory implements Iterable<GenshinItem> {
}
@Override
public
Iterator
<
G
enshin
Item
>
iterator
()
{
public
Iterator
<
G
ame
Item
>
iterator
()
{
return
this
.
getItems
().
values
().
iterator
();
}
}
src/main/java/emu/grasscutter/game/inventory/InventoryTab.java
View file @
01b190bc
package
emu.grasscutter.game.inventory
;
public
interface
InventoryTab
{
public
G
enshin
Item
getItemById
(
int
id
);
public
G
ame
Item
getItemById
(
int
id
);
public
void
onAddItem
(
G
enshin
Item
item
);
public
void
onAddItem
(
G
ame
Item
item
);
public
void
onRemoveItem
(
G
enshin
Item
item
);
public
void
onRemoveItem
(
G
ame
Item
item
);
public
int
getSize
();
...
...
src/main/java/emu/grasscutter/game/inventory/MaterialInventoryTab.java
View file @
01b190bc
...
...
@@ -4,7 +4,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import
it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
;
public
class
MaterialInventoryTab
implements
InventoryTab
{
private
final
Int2ObjectMap
<
G
enshin
Item
>
items
;
private
final
Int2ObjectMap
<
G
ame
Item
>
items
;
private
final
int
maxCapacity
;
public
MaterialInventoryTab
(
int
maxCapacity
)
{
...
...
@@ -13,17 +13,17 @@ public class MaterialInventoryTab implements InventoryTab {
}
@Override
public
G
enshin
Item
getItemById
(
int
id
)
{
public
G
ame
Item
getItemById
(
int
id
)
{
return
this
.
items
.
get
(
id
);
}
@Override
public
void
onAddItem
(
G
enshin
Item
item
)
{
public
void
onAddItem
(
G
ame
Item
item
)
{
this
.
items
.
put
(
item
.
getItemId
(),
item
);
}
@Override
public
void
onRemoveItem
(
G
enshin
Item
item
)
{
public
void
onRemoveItem
(
G
ame
Item
item
)
{
this
.
items
.
remove
(
item
.
getItemId
());
}
...
...
Prev
1
…
4
5
6
7
8
9
10
11
12
…
25
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment