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
31764fe5
Commit
31764fe5
authored
Apr 28, 2022
by
memetrollsXD
Committed by
GitHub
Apr 28, 2022
Browse files
Merge branch 'development' into startMail
parents
5c02fee7
fcb48943
Changes
37
Show whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/game/inventory/Inventory.java
View file @
31764fe5
...
...
@@ -168,7 +168,7 @@ public class Inventory implements Iterable<GameItem> {
}
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
;
...
...
@@ -218,6 +218,7 @@ public class Inventory implements Iterable<GameItem> {
}
// Set ownership and save to db
if
(
item
.
getItemData
().
getItemType
()
!=
ItemType
.
ITEM_VIRTUAL
)
item
.
save
();
return
item
;
...
...
@@ -236,13 +237,14 @@ public class Inventory implements Iterable<GameItem> {
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
;
...
...
src/main/java/emu/grasscutter/game/managers/InventoryManager.java
View file @
31764fe5
...
...
@@ -23,23 +23,7 @@ import emu.grasscutter.game.player.Player;
import
emu.grasscutter.net.proto.ItemParamOuterClass.ItemParam
;
import
emu.grasscutter.net.proto.MaterialInfoOuterClass.MaterialInfo
;
import
emu.grasscutter.server.game.GameServer
;
import
emu.grasscutter.server.packet.send.PacketAbilityChangeNotify
;
import
emu.grasscutter.server.packet.send.PacketAvatarPromoteRsp
;
import
emu.grasscutter.server.packet.send.PacketAvatarPropNotify
;
import
emu.grasscutter.server.packet.send.PacketAvatarSkillChangeNotify
;
import
emu.grasscutter.server.packet.send.PacketAvatarSkillUpgradeRsp
;
import
emu.grasscutter.server.packet.send.PacketAvatarUnlockTalentNotify
;
import
emu.grasscutter.server.packet.send.PacketAvatarUpgradeRsp
;
import
emu.grasscutter.server.packet.send.PacketDestroyMaterialRsp
;
import
emu.grasscutter.server.packet.send.PacketProudSkillChangeNotify
;
import
emu.grasscutter.server.packet.send.PacketProudSkillExtraLevelNotify
;
import
emu.grasscutter.server.packet.send.PacketReliquaryUpgradeRsp
;
import
emu.grasscutter.server.packet.send.PacketSetEquipLockStateRsp
;
import
emu.grasscutter.server.packet.send.PacketStoreItemChangeNotify
;
import
emu.grasscutter.server.packet.send.PacketUnlockAvatarTalentRsp
;
import
emu.grasscutter.server.packet.send.PacketWeaponAwakenRsp
;
import
emu.grasscutter.server.packet.send.PacketWeaponPromoteRsp
;
import
emu.grasscutter.server.packet.send.PacketWeaponUpgradeRsp
;
import
emu.grasscutter.server.packet.send.*
;
import
emu.grasscutter.utils.Utils
;
import
it.unimi.dsi.fastutil.ints.Int2IntMap
;
import
it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap
;
...
...
@@ -734,6 +718,7 @@ public class InventoryManager {
avatar
.
save
();
player
.
sendPacket
(
new
PacketAvatarPropNotify
(
avatar
));
player
.
sendPacket
(
new
PacketAvatarFetterDataNotify
(
avatar
));
}
public
void
upgradeAvatarSkill
(
Player
player
,
long
guid
,
int
skillId
)
{
...
...
src/main/java/emu/grasscutter/game/player/Player.java
View file @
31764fe5
...
...
@@ -21,6 +21,7 @@ import emu.grasscutter.game.inventory.Inventory;
import
emu.grasscutter.game.mail.Mail
;
import
emu.grasscutter.game.props.ActionReason
;
import
emu.grasscutter.game.props.PlayerProperty
;
import
emu.grasscutter.game.shop.ShopInfo
;
import
emu.grasscutter.game.shop.ShopLimit
;
import
emu.grasscutter.game.world.Scene
;
import
emu.grasscutter.game.world.World
;
...
...
@@ -35,6 +36,7 @@ import emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo
import
emu.grasscutter.net.proto.PlayerWorldLocationInfoOuterClass
;
import
emu.grasscutter.net.proto.ProfilePictureOuterClass.ProfilePicture
;
import
emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail
;
import
emu.grasscutter.net.proto.SocialShowAvatarInfoOuterClass
;
import
emu.grasscutter.server.game.GameServer
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.*
;
...
...
@@ -93,6 +95,9 @@ public class Player {
private
int
moonCardDuration
;
private
Set
<
Date
>
moonCardGetTimes
;
private
List
<
Integer
>
showAvatarList
;
private
boolean
showAvatars
;
@Transient
private
boolean
paused
;
@Transient
private
int
enterSceneToken
;
@Transient
private
SceneLoadState
sceneState
;
...
...
@@ -513,6 +518,22 @@ public class Player {
this
.
regionId
=
regionId
;
}
public
void
setShowAvatars
(
boolean
showAvatars
)
{
this
.
showAvatars
=
showAvatars
;
}
public
boolean
isShowAvatars
()
{
return
showAvatars
;
}
public
void
setShowAvatarList
(
List
<
Integer
>
showAvatarList
)
{
this
.
showAvatarList
=
showAvatarList
;
}
public
List
<
Integer
>
getShowAvatarList
()
{
return
showAvatarList
;
}
public
boolean
inMoonCard
()
{
return
moonCard
;
}
...
...
@@ -601,27 +622,26 @@ public class Player {
return
shopLimit
;
}
public
int
getGoodsLimitNum
(
int
goodsId
)
{
for
(
ShopLimit
sl
:
getShopLimit
())
{
if
(
sl
.
getShopGoodId
()
==
goodsId
)
return
sl
.
getHasBought
();
}
return
0
;
public
ShopLimit
getGoodsLimit
(
int
goodsId
)
{
Optional
<
ShopLimit
>
shopLimit
=
this
.
shopLimit
.
stream
().
filter
(
x
->
x
.
getShopGoodId
()
==
goodsId
).
findFirst
();
if
(
shopLimit
.
isEmpty
())
return
null
;
return
shopLimit
.
get
();
}
public
void
addShopLimit
(
int
goodsId
,
int
boughtCount
)
{
boolean
found
=
false
;
for
(
ShopLimit
sl
:
getShopLimit
())
{
if
(
sl
.
getShopGoodId
()
==
goodsId
){
sl
.
setHasBought
(
sl
.
getHasBought
()
+
boughtCount
);
found
=
true
;
}
}
if
(!
found
)
{
public
void
addShopLimit
(
int
goodsId
,
int
boughtCount
,
int
nextRefreshTime
)
{
ShopLimit
target
=
getGoodsLimit
(
goodsId
);
if
(
target
!=
null
)
{
target
.
setHasBought
(
target
.
getHasBought
()
+
boughtCount
);
target
.
setHasBoughtInPeriod
(
target
.
getHasBoughtInPeriod
()
+
boughtCount
);
target
.
setNextRefreshTime
(
nextRefreshTime
);
}
else
{
ShopLimit
sl
=
new
ShopLimit
();
sl
.
setShopGoodId
(
goodsId
);
sl
.
setHasBought
(
boughtCount
);
shopLimit
.
add
(
sl
);
sl
.
setHasBoughtInPeriod
(
boughtCount
);
sl
.
setNextRefreshTime
(
nextRefreshTime
);
getShopLimit
().
add
(
sl
);
}
this
.
save
();
}
...
...
@@ -832,6 +852,38 @@ public class Player {
}
public
SocialDetail
.
Builder
getSocialDetail
()
{
List
<
SocialShowAvatarInfoOuterClass
.
SocialShowAvatarInfo
>
socialShowAvatarInfoList
=
new
ArrayList
<>();
if
(
this
.
isOnline
())
{
if
(
this
.
getShowAvatarList
()
!=
null
)
{
for
(
int
avatarId
:
this
.
getShowAvatarList
())
{
socialShowAvatarInfoList
.
add
(
socialShowAvatarInfoList
.
size
(),
SocialShowAvatarInfoOuterClass
.
SocialShowAvatarInfo
.
newBuilder
()
.
setAvatarId
(
avatarId
)
.
setLevel
(
getAvatars
().
getAvatarById
(
avatarId
).
getLevel
())
.
setCostumeId
(
getAvatars
().
getAvatarById
(
avatarId
).
getCostume
())
.
build
()
);
}
}
}
else
{
List
<
Integer
>
showAvatarList
=
DatabaseHelper
.
getPlayerById
(
id
).
getShowAvatarList
();
AvatarStorage
avatars
=
DatabaseHelper
.
getPlayerById
(
id
).
getAvatars
();
avatars
.
loadFromDatabase
();
if
(
showAvatarList
!=
null
)
{
for
(
int
avatarId
:
showAvatarList
)
{
socialShowAvatarInfoList
.
add
(
socialShowAvatarInfoList
.
size
(),
SocialShowAvatarInfoOuterClass
.
SocialShowAvatarInfo
.
newBuilder
()
.
setAvatarId
(
avatarId
)
.
setLevel
(
avatars
.
getAvatarById
(
avatarId
).
getLevel
())
.
setCostumeId
(
avatars
.
getAvatarById
(
avatarId
).
getCostume
())
.
build
()
);
}
}
}
SocialDetail
.
Builder
social
=
SocialDetail
.
newBuilder
()
.
setUid
(
this
.
getUid
())
.
setProfilePicture
(
ProfilePicture
.
newBuilder
().
setAvatarId
(
this
.
getHeadImage
()))
...
...
@@ -841,6 +893,8 @@ public class Player {
.
setBirthday
(
this
.
getBirthday
().
getFilledProtoWhenNotEmpty
())
.
setWorldLevel
(
this
.
getWorldLevel
())
.
setNameCardId
(
this
.
getNameCardId
())
.
setIsShowAvatar
(
this
.
isShowAvatars
())
.
addAllShowAvatarInfoList
(
socialShowAvatarInfoList
)
.
setFinishAchievementNum
(
0
);
return
social
;
}
...
...
src/main/java/emu/grasscutter/game/shop/ShopInfo.java
View file @
31764fe5
package
emu.grasscutter.game.shop
;
import
emu.grasscutter.data.common.ItemParamData
;
import
emu.grasscutter.data.def.ShopGoodsData
;
import
java.util.ArrayList
;
import
java.util.List
;
...
...
@@ -14,7 +15,6 @@ public class ShopInfo {
private
int
buyLimit
=
0
;
private
int
beginTime
=
0
;
private
int
endTime
=
1924992000
;
private
int
nextRefreshTime
=
1924992000
;
private
int
minLevel
=
0
;
private
int
maxLevel
=
61
;
private
List
<
Integer
>
preGoodsIdList
=
new
ArrayList
<>();
...
...
@@ -23,6 +23,43 @@ public class ShopInfo {
private
int
disableType
=
0
;
private
int
secondarySheetId
=
0
;
private
String
refreshType
;
public
enum
ShopRefreshType
{
NONE
(
0
),
SHOP_REFRESH_DAILY
(
1
),
SHOP_REFRESH_WEEKLY
(
2
),
SHOP_REFRESH_MONTHLY
(
3
);
private
final
int
value
;
ShopRefreshType
(
int
value
)
{
this
.
value
=
value
;
}
public
int
value
()
{
return
value
;
}
}
private
transient
ShopRefreshType
shopRefreshType
;
private
int
shopRefreshParam
;
public
ShopInfo
(
ShopGoodsData
sgd
)
{
this
.
goodsId
=
sgd
.
getGoodsId
();
this
.
goodsItem
=
new
ItemParamData
(
sgd
.
getItemId
(),
sgd
.
getItemCount
());
this
.
scoin
=
sgd
.
getCostScoin
();
this
.
mcoin
=
sgd
.
getCostMcoin
();
this
.
hcoin
=
sgd
.
getCostHcoin
();
this
.
buyLimit
=
sgd
.
getBuyLimit
();
this
.
minLevel
=
sgd
.
getMinPlayerLevel
();
this
.
maxLevel
=
sgd
.
getMaxPlayerLevel
();
this
.
costItemList
=
sgd
.
getCostItems
().
stream
().
filter
(
x
->
x
.
getId
()
!=
0
).
map
(
x
->
new
ItemParamData
(
x
.
getId
(),
x
.
getCount
())).
toList
();
this
.
secondarySheetId
=
sgd
.
getSubTabId
();
this
.
shopRefreshType
=
sgd
.
getRefreshType
();
this
.
shopRefreshParam
=
sgd
.
getRefreshParam
();
}
public
int
getHcoin
()
{
return
hcoin
;
}
...
...
@@ -127,14 +164,6 @@ public class ShopInfo {
this
.
endTime
=
endTime
;
}
public
int
getNextRefreshTime
()
{
return
nextRefreshTime
;
}
public
void
setNextRefreshTime
(
int
nextRefreshTime
)
{
this
.
nextRefreshTime
=
nextRefreshTime
;
}
public
int
getMinLevel
()
{
return
minLevel
;
}
...
...
@@ -150,4 +179,27 @@ public class ShopInfo {
public
void
setMaxLevel
(
int
maxLevel
)
{
this
.
maxLevel
=
maxLevel
;
}
public
ShopRefreshType
getShopRefreshType
()
{
if
(
refreshType
==
null
)
return
ShopRefreshType
.
NONE
;
return
switch
(
refreshType
)
{
case
"SHOP_REFRESH_DAILY"
->
ShopInfo
.
ShopRefreshType
.
SHOP_REFRESH_DAILY
;
case
"SHOP_REFRESH_WEEKLY"
->
ShopInfo
.
ShopRefreshType
.
SHOP_REFRESH_WEEKLY
;
case
"SHOP_REFRESH_MONTHLY"
->
ShopInfo
.
ShopRefreshType
.
SHOP_REFRESH_MONTHLY
;
default
->
ShopInfo
.
ShopRefreshType
.
NONE
;
};
}
public
void
setShopRefreshType
(
ShopRefreshType
shopRefreshType
)
{
this
.
shopRefreshType
=
shopRefreshType
;
}
public
int
getShopRefreshParam
()
{
return
shopRefreshParam
;
}
public
void
setShopRefreshParam
(
int
shopRefreshParam
)
{
this
.
shopRefreshParam
=
shopRefreshParam
;
}
}
src/main/java/emu/grasscutter/game/shop/ShopLimit.java
View file @
31764fe5
...
...
@@ -20,6 +20,24 @@ public class ShopLimit {
this
.
hasBought
=
hasBought
;
}
public
int
getNextRefreshTime
()
{
return
nextRefreshTime
;
}
public
void
setNextRefreshTime
(
int
nextRefreshTime
)
{
this
.
nextRefreshTime
=
nextRefreshTime
;
}
public
int
getHasBoughtInPeriod
()
{
return
hasBoughtInPeriod
;
}
public
void
setHasBoughtInPeriod
(
int
hasBoughtInPeriod
)
{
this
.
hasBoughtInPeriod
=
hasBoughtInPeriod
;
}
private
int
shopGoodId
;
private
int
hasBought
;
private
int
hasBoughtInPeriod
=
0
;
private
int
nextRefreshTime
=
0
;
}
src/main/java/emu/grasscutter/game/shop/ShopManager.java
View file @
31764fe5
...
...
@@ -2,12 +2,20 @@ package emu.grasscutter.game.shop;
import
com.google.gson.reflect.TypeToken
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.common.ItemParamData
;
import
emu.grasscutter.data.def.ShopGoodsData
;
import
emu.grasscutter.net.proto.ItemParamOuterClass
;
import
emu.grasscutter.net.proto.ShopGoodsOuterClass
;
import
emu.grasscutter.server.game.GameServer
;
import
emu.grasscutter.utils.Utils
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectMap
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
;
import
java.io.FileReader
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.Iterator
;
import
java.util.List
;
public
class
ShopManager
{
...
...
@@ -25,18 +33,57 @@ public class ShopManager {
this
.
load
();
}
private
static
final
int
REFRESH_HOUR
=
4
;
// In GMT+8 server
private
static
final
String
TIME_ZONE
=
"Asia/Shanghai"
;
// GMT+8 Timezone
public
static
int
getShopNextRefreshTime
(
ShopInfo
shopInfo
)
{
return
switch
(
shopInfo
.
getShopRefreshType
())
{
case
SHOP_REFRESH_DAILY
->
Utils
.
GetNextTimestampOfThisHour
(
REFRESH_HOUR
,
TIME_ZONE
,
shopInfo
.
getShopRefreshParam
());
case
SHOP_REFRESH_WEEKLY
->
Utils
.
GetNextTimestampOfThisHourInNextWeek
(
REFRESH_HOUR
,
TIME_ZONE
,
shopInfo
.
getShopRefreshParam
());
case
SHOP_REFRESH_MONTHLY
->
Utils
.
GetNextTimestampOfThisHourInNextMonth
(
REFRESH_HOUR
,
TIME_ZONE
,
shopInfo
.
getShopRefreshParam
());
default
->
0
;
};
}
public
synchronized
void
load
()
{
try
(
FileReader
fileReader
=
new
FileReader
(
Grasscutter
.
getConfig
().
DATA_FOLDER
+
"Shop.json"
))
{
getShopData
().
clear
();
List
<
ShopTable
>
banners
=
Grasscutter
.
getGsonFactory
().
fromJson
(
fileReader
,
TypeToken
.
getParameterized
(
Collection
.
class
,
ShopTable
.
class
).
getType
());
if
(
banners
.
size
()
>
0
)
{
for
(
ShopTable
shopTable
:
banners
)
{
for
(
ShopInfo
cost
:
shopTable
.
getItems
())
{
if
(
cost
.
getCostItemList
()
!=
null
)
{
Iterator
<
ItemParamData
>
iterator
=
cost
.
getCostItemList
().
iterator
();
while
(
iterator
.
hasNext
())
{
ItemParamData
ipd
=
iterator
.
next
();
if
(
ipd
.
getId
()
==
201
)
{
cost
.
setHcoin
(
cost
.
getHcoin
()
+
ipd
.
getCount
());
iterator
.
remove
();
}
if
(
ipd
.
getId
()
==
203
)
{
cost
.
setMcoin
(
cost
.
getMcoin
()
+
ipd
.
getCount
());
iterator
.
remove
();
}
}
}
}
getShopData
().
put
(
shopTable
.
getShopId
(),
shopTable
.
getItems
());
}
Grasscutter
.
getLogger
().
info
(
"Shop data successfully loaded."
);
}
else
{
Grasscutter
.
getLogger
().
error
(
"Unable to load shop data. Shop data size is 0."
);
}
if
(
Grasscutter
.
getConfig
().
getGameServerOptions
().
EnableOfficialShop
)
{
GameData
.
getShopGoodsDataEntries
().
forEach
((
k
,
v
)
->
{
if
(!
getShopData
().
containsKey
(
k
.
intValue
()))
getShopData
().
put
(
k
.
intValue
(),
new
ArrayList
<>());
for
(
ShopGoodsData
sgd
:
v
)
{
var
shopInfo
=
new
ShopInfo
(
sgd
);
getShopData
().
get
(
k
.
intValue
()).
add
(
shopInfo
);
}
});
}
}
catch
(
Exception
e
)
{
// TODO Auto-generated catch block
e
.
printStackTrace
();
...
...
src/main/java/emu/grasscutter/net/packet/PacketOpcodes.java
View file @
31764fe5
...
...
@@ -1172,6 +1172,11 @@ public class PacketOpcodes {
public
static
final
int
UseWidgetCreateGadgetRsp
=
4290
;
public
static
final
int
UseWidgetRetractGadgetReq
=
4255
;
public
static
final
int
UseWidgetRetractGadgetRsp
=
4297
;
public
static
final
int
VehicleSpawnReq
=
809
;
public
static
final
int
VehicleSpawnRsp
=
865
;
public
static
final
int
VehicleInteractReq
=
862
;
public
static
final
int
VehicleInteractRsp
=
889
;
public
static
final
int
VehicleStaminaNotify
=
866
;
public
static
final
int
ViewCodexReq
=
4210
;
public
static
final
int
ViewCodexRsp
=
4209
;
public
static
final
int
WatcherAllDataNotify
=
2260
;
...
...
src/main/java/emu/grasscutter/server/game/GameServer.java
View file @
31764fe5
...
...
@@ -189,6 +189,10 @@ public final class GameServer extends KcpServer {
world
.
onTick
();
}
for
(
Player
player
:
this
.
getPlayers
().
values
())
{
player
.
onTick
();
}
ServerTickEvent
event
=
new
ServerTickEvent
();
event
.
call
();
}
...
...
src/main/java/emu/grasscutter/server/packet/recv/HandlerBuyGoodsReq.java
View file @
31764fe5
package
emu.grasscutter.server.packet.recv
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.common.ItemParamData
;
import
emu.grasscutter.game.inventory.GameItem
;
import
emu.grasscutter.game.props.ActionReason
;
import
emu.grasscutter.game.props.PlayerProperty
;
import
emu.grasscutter.game.shop.ShopInfo
;
import
emu.grasscutter.game.shop.ShopLimit
;
import
emu.grasscutter.game.shop.ShopManager
;
import
emu.grasscutter.net.packet.Opcodes
;
import
emu.grasscutter.net.packet.PacketHandler
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
...
...
@@ -13,9 +17,11 @@ import emu.grasscutter.net.proto.ShopGoodsOuterClass;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.PacketBuyGoodsRsp
;
import
emu.grasscutter.server.packet.send.PacketStoreItemChangeNotify
;
import
emu.grasscutter.utils.Utils
;
import
java.util.ArrayList
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Optional
;
@Opcodes
(
PacketOpcodes
.
BuyGoodsReq
)
...
...
@@ -24,8 +30,34 @@ public class HandlerBuyGoodsReq extends PacketHandler {
@Override
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
BuyGoodsReqOuterClass
.
BuyGoodsReq
buyGoodsReq
=
BuyGoodsReqOuterClass
.
BuyGoodsReq
.
parseFrom
(
payload
);
List
<
ShopInfo
>
configShop
=
session
.
getServer
().
getShopManager
().
getShopData
().
get
(
buyGoodsReq
.
getShopType
());
if
(
configShop
==
null
)
return
;
// Don't trust your users' input
List
<
Integer
>
targetShopGoodsId
=
buyGoodsReq
.
getGoodsListList
().
stream
().
map
(
ShopGoodsOuterClass
.
ShopGoods
::
getGoodsId
).
toList
();
for
(
int
goodsId
:
targetShopGoodsId
)
{
Optional
<
ShopInfo
>
sg2
=
configShop
.
stream
().
filter
(
x
->
x
.
getGoodsId
()
==
goodsId
).
findFirst
();
if
(
sg2
.
isEmpty
())
continue
;
ShopInfo
sg
=
sg2
.
get
();
int
currentTs
=
Utils
.
getCurrentSeconds
();
ShopLimit
shopLimit
=
session
.
getPlayer
().
getGoodsLimit
(
sg
.
getGoodsId
());
int
bought
=
0
;
if
(
shopLimit
!=
null
)
{
if
(
currentTs
>
shopLimit
.
getNextRefreshTime
())
{
shopLimit
.
setNextRefreshTime
(
ShopManager
.
getShopNextRefreshTime
(
sg
));
}
else
{
bought
=
shopLimit
.
getHasBoughtInPeriod
();
}
session
.
getPlayer
().
save
();
}
if
(
bought
+
buyGoodsReq
.
getBoughtNum
()
>
sg
.
getBuyLimit
())
{
return
;
}
for
(
ShopGoodsOuterClass
.
ShopGoods
sg
:
buyGoodsReq
.
getGoodsListList
())
{
if
(
sg
.
getScoin
()
>
0
&&
session
.
getPlayer
().
getMora
()
<
buyGoodsReq
.
getBoughtNum
()
*
sg
.
getScoin
())
{
return
;
}
...
...
@@ -37,12 +69,14 @@ public class HandlerBuyGoodsReq extends PacketHandler {
}
HashMap
<
GameItem
,
Integer
>
itemsCache
=
new
HashMap
<>();
for
(
ItemParamOuterClass
.
ItemParam
p
:
sg
.
getCostItemListList
())
{
Optional
<
GameItem
>
invItem
=
session
.
getPlayer
().
getInventory
().
getItems
().
values
().
stream
().
filter
(
x
->
x
.
getItemId
()
==
p
.
getItemId
()).
findFirst
();
if
(
sg
.
getCostItemList
()
!=
null
)
{
for
(
ItemParamData
p
:
sg
.
getCostItemList
())
{
Optional
<
GameItem
>
invItem
=
session
.
getPlayer
().
getInventory
().
getItems
().
values
().
stream
().
filter
(
x
->
x
.
getItemId
()
==
p
.
getId
()).
findFirst
();
if
(
invItem
.
isEmpty
()
||
invItem
.
get
().
getCount
()
<
p
.
getCount
())
return
;
itemsCache
.
put
(
invItem
.
get
(),
p
.
getCount
()
*
buyGoodsReq
.
getBoughtNum
());
}
}
session
.
getPlayer
().
setMora
(
session
.
getPlayer
().
getMora
()
-
buyGoodsReq
.
getBoughtNum
()
*
sg
.
getScoin
());
session
.
getPlayer
().
setPrimogems
(
session
.
getPlayer
().
getPrimogems
()
-
buyGoodsReq
.
getBoughtNum
()
*
sg
.
getHcoin
());
...
...
@@ -55,11 +89,11 @@ public class HandlerBuyGoodsReq extends PacketHandler {
itemsCache
.
clear
();
}
session
.
getPlayer
().
addShopLimit
(
sg
.
getGoodsId
(),
buyGoodsReq
.
getBoughtNum
());
GameItem
item
=
new
GameItem
(
GameData
.
getItemDataMap
().
get
(
sg
.
getGoodsItem
().
getI
temI
d
()));
session
.
getPlayer
().
addShopLimit
(
sg
.
getGoodsId
(),
buyGoodsReq
.
getBoughtNum
()
,
ShopManager
.
getShopNextRefreshTime
(
sg
)
);
GameItem
item
=
new
GameItem
(
GameData
.
getItemDataMap
().
get
(
sg
.
getGoodsItem
().
getId
()));
item
.
setCount
(
buyGoodsReq
.
getBoughtNum
()
*
sg
.
getGoodsItem
().
getCount
());
session
.
getPlayer
().
getInventory
().
addItem
(
item
,
ActionReason
.
Shop
,
true
);
// fix: not notify when got virtual item from shop
session
.
send
(
new
PacketBuyGoodsRsp
(
buyGoodsReq
.
getShopType
(),
session
.
getPlayer
().
getGoodsLimit
Num
(
sg
.
getGoodsId
())
,
sg
));
session
.
send
(
new
PacketBuyGoodsRsp
(
buyGoodsReq
.
getShopType
(),
session
.
getPlayer
().
getGoodsLimit
(
sg
.
getGoodsId
())
.
getHasBoughtInPeriod
(),
buyGoodsReq
.
getGoodsListList
().
stream
().
filter
(
x
->
x
.
getGoodsId
()
==
goodsId
).
findFirst
().
get
()
));
}
session
.
getPlayer
().
save
();
...
...
src/main/java/emu/grasscutter/server/packet/recv/HandlerUpdatePlayerShowAvatarListReq.java
0 → 100644
View file @
31764fe5
package
emu.grasscutter.server.packet.recv
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.net.packet.Opcodes
;
import
emu.grasscutter.net.packet.PacketHandler
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.UpdatePlayerShowAvatarListReqOuterClass
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.PacketUpdatePlayerShowAvatarListRsp
;
@Opcodes
(
PacketOpcodes
.
UpdatePlayerShowAvatarListReq
)
public
class
HandlerUpdatePlayerShowAvatarListReq
extends
PacketHandler
{
@Override
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
UpdatePlayerShowAvatarListReqOuterClass
.
UpdatePlayerShowAvatarListReq
req
=
UpdatePlayerShowAvatarListReqOuterClass
.
UpdatePlayerShowAvatarListReq
.
parseFrom
(
payload
);
session
.
getPlayer
().
setShowAvatars
(
req
.
getIsShowAvatar
());
session
.
getPlayer
().
setShowAvatarList
(
req
.
getShowAvatarIdListList
());
session
.
send
(
new
PacketUpdatePlayerShowAvatarListRsp
(
req
.
getIsShowAvatar
(),
req
.
getShowAvatarIdListList
()));
}
}
src/main/java/emu/grasscutter/server/packet/recv/HandlerVehicleInteractReq.java
0 → 100644
View file @
31764fe5
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.VehicleInteractReqOuterClass
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.PacketVehicleInteractRsp
;
@Opcodes
(
PacketOpcodes
.
VehicleInteractReq
)
public
class
HandlerVehicleInteractReq
extends
PacketHandler
{
@Override
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
VehicleInteractReqOuterClass
.
VehicleInteractReq
req
=
VehicleInteractReqOuterClass
.
VehicleInteractReq
.
parseFrom
(
payload
);
session
.
send
(
new
PacketVehicleInteractRsp
(
session
.
getPlayer
(),
req
.
getEntityId
(),
req
.
getInteractType
()));
}
}
src/main/java/emu/grasscutter/server/packet/recv/HandlerVehicleSpawnReq.java
0 → 100644
View file @
31764fe5
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.VehicleSpawnReqOuterClass
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.PacketVehicleSpawnRsp
;
import
emu.grasscutter.utils.Position
;
@Opcodes
(
PacketOpcodes
.
VehicleSpawnReq
)
public
class
HandlerVehicleSpawnReq
extends
PacketHandler
{
@Override
public
void
handle
(
GameSession
session
,
byte
[]
header
,
byte
[]
payload
)
throws
Exception
{
VehicleSpawnReqOuterClass
.
VehicleSpawnReq
req
=
VehicleSpawnReqOuterClass
.
VehicleSpawnReq
.
parseFrom
(
payload
);
session
.
send
(
new
PacketVehicleSpawnRsp
(
session
.
getPlayer
(),
req
.
getVehicleId
(),
req
.
getPointId
(),
new
Position
(
req
.
getPos
()),
new
Position
(
req
.
getRot
())));
}
}
src/main/java/emu/grasscutter/server/packet/send/PacketGetShopRsp.java
View file @
31764fe5
...
...
@@ -3,6 +3,7 @@ package emu.grasscutter.server.packet.send;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.shop.ShopInfo
;
import
emu.grasscutter.game.shop.ShopLimit
;
import
emu.grasscutter.game.shop.ShopManager
;
import
emu.grasscutter.net.packet.BasePacket
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
...
...
@@ -10,13 +11,13 @@ import emu.grasscutter.net.proto.GetShopRspOuterClass;
import
emu.grasscutter.net.proto.ItemParamOuterClass
;
import
emu.grasscutter.net.proto.ShopGoodsOuterClass.ShopGoods
;
import
emu.grasscutter.net.proto.ShopOuterClass.Shop
;
import
emu.grasscutter.utils.Utils
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.stream.Collectors
;
public
class
PacketGetShopRsp
extends
BasePacket
{
public
PacketGetShopRsp
(
Player
inv
,
int
shopType
)
{
super
(
PacketOpcodes
.
GetShopRsp
);
...
...
@@ -36,25 +37,42 @@ public class PacketGetShopRsp extends BasePacket {
.
setGoodsItem
(
ItemParamOuterClass
.
ItemParam
.
newBuilder
().
setItemId
(
info
.
getGoodsItem
().
getId
()).
setCount
(
info
.
getGoodsItem
().
getCount
()).
build
())
.
setScoin
(
info
.
getScoin
())
.
setHcoin
(
info
.
getHcoin
())
.
setBoughtNum
(
inv
.
getGoodsLimitNum
(
info
.
getGoodsId
()))
.
setBuyLimit
(
info
.
getBuyLimit
())
.
setBeginTime
(
info
.
getBeginTime
())
.
setEndTime
(
info
.
getEndTime
())
.
setNextRefreshTime
(
info
.
getNextRefreshTime
())
.
setMinLevel
(
info
.
getMinLevel
())
.
setMaxLevel
(
info
.
getMaxLevel
())
.
addAllPreGoodsIdList
(
info
.
getPreGoodsIdList
())
.
setMcoin
(
info
.
getMcoin
())
.
setDisableType
(
info
.
getDisableType
())
.
setSecondarySheetId
(
info
.
getSecondarySheetId
());
if
(
info
.
getCostItemList
()
!=
null
)
{
goods
.
addAllCostItemList
(
info
.
getCostItemList
().
stream
().
map
(
x
->
ItemParamOuterClass
.
ItemParam
.
newBuilder
().
setItemId
(
x
.
getId
()).
setCount
(
x
.
getCount
()).
build
()).
collect
(
Collectors
.
toList
()));
}
if
(
info
.
getPreGoodsIdList
()
!=
null
)
{
goods
.
addAllPreGoodsIdList
(
info
.
getPreGoodsIdList
());
}
int
currentTs
=
Utils
.
getCurrentSeconds
();
ShopLimit
currentShopLimit
=
inv
.
getGoodsLimit
(
info
.
getGoodsId
());
int
nextRefreshTime
=
ShopManager
.
getShopNextRefreshTime
(
info
);
if
(
currentShopLimit
!=
null
)
{
if
(
currentShopLimit
.
getNextRefreshTime
()
<
currentTs
)
{
// second game day
currentShopLimit
.
setHasBoughtInPeriod
(
0
);
currentShopLimit
.
setNextRefreshTime
(
nextRefreshTime
);
}
goods
.
setBoughtNum
(
currentShopLimit
.
getHasBoughtInPeriod
());
goods
.
setNextRefreshTime
(
currentShopLimit
.
getNextRefreshTime
());
}
else
{
inv
.
addShopLimit
(
goods
.
getGoodsId
(),
0
,
nextRefreshTime
);
// save generated refresh time
goods
.
setNextRefreshTime
(
nextRefreshTime
);
}
goodsList
.
add
(
goods
.
build
());
}
shop
.
addAllGoodsList
(
goodsList
);
}
inv
.
save
();
this
.
setData
(
GetShopRspOuterClass
.
GetShopRsp
.
newBuilder
().
setShop
(
shop
).
build
());
}
}
src/main/java/emu/grasscutter/server/packet/send/PacketUpdatePlayerShowAvatarListRsp.java
0 → 100644
View file @
31764fe5
package
emu.grasscutter.server.packet.send
;
import
emu.grasscutter.net.packet.BasePacket
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.UpdatePlayerShowAvatarListRspOuterClass.UpdatePlayerShowAvatarListRsp
;
import
java.util.List
;
public
class
PacketUpdatePlayerShowAvatarListRsp
extends
BasePacket
{
public
PacketUpdatePlayerShowAvatarListRsp
(
boolean
isShowAvatar
,
List
<
Integer
>
avatarIds
)
{
super
(
PacketOpcodes
.
UpdatePlayerShowAvatarListRsp
);
UpdatePlayerShowAvatarListRsp
proto
=
UpdatePlayerShowAvatarListRsp
.
newBuilder
()
.
setIsShowAvatar
(
isShowAvatar
)
.
addAllShowAvatarIdList
(
avatarIds
)
.
setRetcode
(
0
)
.
build
();
this
.
setData
(
proto
);
}
}
src/main/java/emu/grasscutter/server/packet/send/PacketVehicleInteractRsp.java
0 → 100644
View file @
31764fe5
package
emu.grasscutter.server.packet.send
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.entity.GameEntity
;
import
emu.grasscutter.net.packet.BasePacket
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.VehicleInteractTypeOuterClass.VehicleInteractType
;
import
emu.grasscutter.net.proto.VehicleInteractRspOuterClass.VehicleInteractRsp
;
import
emu.grasscutter.net.proto.VehicleMemberOuterClass.VehicleMember
;
public
class
PacketVehicleInteractRsp
extends
BasePacket
{
public
PacketVehicleInteractRsp
(
Player
player
,
int
entityId
,
VehicleInteractType
interactType
)
{
super
(
PacketOpcodes
.
VehicleInteractRsp
);
VehicleInteractRsp
.
Builder
proto
=
VehicleInteractRsp
.
newBuilder
();
GameEntity
vehicle
=
player
.
getScene
().
getEntityById
(
entityId
);
if
(
vehicle
!=
null
)
{
proto
.
setEntityId
(
vehicle
.
getId
());
proto
.
setInteractType
(
interactType
);
VehicleMember
vehicleMember
=
VehicleMember
.
newBuilder
()
.
setUid
(
player
.
getUid
())
.
setAvatarGuid
(
player
.
getTeamManager
().
getCurrentCharacterGuid
())
.
build
();
proto
.
setMember
(
vehicleMember
);
}
this
.
setData
(
proto
.
build
());
}
}
src/main/java/emu/grasscutter/server/packet/send/PacketVehicleSpawnRsp.java
0 → 100644
View file @
31764fe5
package
emu.grasscutter.server.packet.send
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.entity.EntityVehicle
;
import
emu.grasscutter.game.props.FightProperty
;
import
emu.grasscutter.game.entity.GameEntity
;
import
emu.grasscutter.net.packet.BasePacket
;
import
emu.grasscutter.net.packet.PacketOpcodes
;
import
emu.grasscutter.net.proto.VehicleSpawnRspOuterClass.VehicleSpawnRsp
;
import
emu.grasscutter.utils.Position
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectMap
;
public
class
PacketVehicleSpawnRsp
extends
BasePacket
{
public
PacketVehicleSpawnRsp
(
Player
player
,
int
vehicleId
,
int
pointId
,
Position
pos
,
Position
rot
)
{
super
(
PacketOpcodes
.
VehicleSpawnRsp
);
VehicleSpawnRsp
.
Builder
proto
=
VehicleSpawnRsp
.
newBuilder
();
EntityVehicle
vehicle
=
new
EntityVehicle
(
player
.
getScene
(),
player
,
vehicleId
,
pointId
,
pos
,
rot
);
switch
(
vehicleId
)
{
// TODO: Not hardcode this. Waverider (skiff)
case
45001001
,
45001002
->
{
vehicle
.
addFightProperty
(
FightProperty
.
FIGHT_PROP_BASE_HP
,
10000
);
vehicle
.
addFightProperty
(
FightProperty
.
FIGHT_PROP_BASE_ATTACK
,
100
);
vehicle
.
addFightProperty
(
FightProperty
.
FIGHT_PROP_CUR_ATTACK
,
100
);
vehicle
.
addFightProperty
(
FightProperty
.
FIGHT_PROP_CUR_HP
,
10000
);
vehicle
.
addFightProperty
(
FightProperty
.
FIGHT_PROP_CUR_DEFENSE
,
0
);
vehicle
.
addFightProperty
(
FightProperty
.
FIGHT_PROP_CUR_SPEED
,
0
);
vehicle
.
addFightProperty
(
FightProperty
.
FIGHT_PROP_CHARGE_EFFICIENCY
,
0
);
vehicle
.
addFightProperty
(
FightProperty
.
FIGHT_PROP_MAX_HP
,
10000
);
}
default
->
{}
}
player
.
getScene
().
addEntity
(
vehicle
);
proto
.
setVehicleId
(
vehicleId
);
proto
.
setEntityId
(
vehicle
.
getId
());
this
.
setData
(
proto
.
build
());
}
}
src/main/java/emu/grasscutter/utils/Utils.java
View file @
31764fe5
...
...
@@ -3,6 +3,8 @@ package emu.grasscutter.utils;
import
java.io.*
;
import
java.nio.file.Files
;
import
java.nio.file.StandardCopyOption
;
import
java.time.*
;
import
java.time.temporal.TemporalAdjusters
;
import
java.util.Random
;
import
emu.grasscutter.Config
;
...
...
@@ -191,4 +193,40 @@ public final class Utils {
if
(
exit
)
System
.
exit
(
1
);
}
public
static
int
GetNextTimestampOfThisHour
(
int
hour
,
String
timeZone
,
int
param
)
{
ZonedDateTime
zonedDateTime
=
ZonedDateTime
.
now
(
ZoneId
.
of
(
timeZone
));
for
(
int
i
=
0
;
i
<
param
;
i
++){
if
(
zonedDateTime
.
getHour
()
<
hour
)
{
zonedDateTime
=
zonedDateTime
.
withHour
(
hour
).
withMinute
(
0
).
withSecond
(
0
);
}
else
{
zonedDateTime
=
zonedDateTime
.
plusDays
(
1
).
withHour
(
hour
).
withMinute
(
0
).
withSecond
(
0
);
}
}
return
(
int
)
zonedDateTime
.
toInstant
().
atZone
(
ZoneOffset
.
UTC
).
toEpochSecond
();
}
public
static
int
GetNextTimestampOfThisHourInNextWeek
(
int
hour
,
String
timeZone
,
int
param
)
{
ZonedDateTime
zonedDateTime
=
ZonedDateTime
.
now
(
ZoneId
.
of
(
timeZone
));
for
(
int
i
=
0
;
i
<
param
;
i
++)
{
if
(
zonedDateTime
.
getDayOfWeek
()
==
DayOfWeek
.
MONDAY
&&
zonedDateTime
.
getHour
()
<
hour
)
{
zonedDateTime
=
ZonedDateTime
.
now
(
ZoneId
.
of
(
timeZone
)).
withHour
(
hour
).
withMinute
(
0
).
withSecond
(
0
);
}
else
{
zonedDateTime
=
zonedDateTime
.
with
(
TemporalAdjusters
.
next
(
DayOfWeek
.
MONDAY
)).
withHour
(
hour
).
withMinute
(
0
).
withSecond
(
0
);
}
}
return
(
int
)
zonedDateTime
.
toInstant
().
atZone
(
ZoneOffset
.
UTC
).
toEpochSecond
();
}
public
static
int
GetNextTimestampOfThisHourInNextMonth
(
int
hour
,
String
timeZone
,
int
param
)
{
ZonedDateTime
zonedDateTime
=
ZonedDateTime
.
now
(
ZoneId
.
of
(
timeZone
));
for
(
int
i
=
0
;
i
<
param
;
i
++)
{
if
(
zonedDateTime
.
getDayOfMonth
()
==
1
&&
zonedDateTime
.
getHour
()
<
hour
)
{
zonedDateTime
=
ZonedDateTime
.
now
(
ZoneId
.
of
(
timeZone
)).
withHour
(
hour
).
withMinute
(
0
).
withSecond
(
0
);
}
else
{
zonedDateTime
=
zonedDateTime
.
with
(
TemporalAdjusters
.
firstDayOfNextMonth
()).
withHour
(
hour
).
withMinute
(
0
).
withSecond
(
0
);
}
}
return
(
int
)
zonedDateTime
.
toInstant
().
atZone
(
ZoneOffset
.
UTC
).
toEpochSecond
();
}
}
Prev
1
2
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