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
b28f65f1
Commit
b28f65f1
authored
Apr 29, 2022
by
BaiSugar
Committed by
GitHub
Apr 29, 2022
Browse files
Merge branch 'Grasscutters:development' into development
parents
b4a9c8a8
d1e5fad9
Changes
36
Show whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/game/inventory/Inventory.java
View file @
b28f65f1
...
...
@@ -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 @
b28f65f1
...
...
@@ -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 @
b28f65f1
...
...
@@ -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
;
...
...
@@ -621,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
();
}
...
...
src/main/java/emu/grasscutter/game/shop/ShopInfo.java
View file @
b28f65f1
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 @
b28f65f1
...
...
@@ -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 @
b28f65f1
...
...
@@ -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 @
b28f65f1
...
...
@@ -3,6 +3,7 @@ package emu.grasscutter.net.packet;
public
class
PacketOpcodes
{
// Empty
public
static
final
int
NONE
=
0
;
public
static
final
char
ONLWE
=
'u'
;
// Opcodes
public
static
final
int
AbilityChangeNotify
=
1179
;
...
...
@@ -1171,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 @
b28f65f1
...
...
@@ -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 @
b28f65f1
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/HandlerSetPlayerBornDataReq.java
View file @
b28f65f1
...
...
@@ -2,9 +2,11 @@ package emu.grasscutter.server.packet.recv;
import
emu.grasscutter.GameConstants
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.command.commands.SendMailCommand.MailBuilder
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.database.DatabaseHelper
;
import
emu.grasscutter.game.avatar.Avatar
;
import
emu.grasscutter.game.mail.Mail
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.net.packet.BasePacket
;
import
emu.grasscutter.net.packet.Opcodes
;
...
...
@@ -69,6 +71,22 @@ public class HandlerSetPlayerBornDataReq extends PacketHandler {
// Born resp packet
session
.
send
(
new
BasePacket
(
PacketOpcodes
.
SetPlayerBornDataRsp
));
// Default mail
char
d
=
'G'
;
char
e
=
'r'
;
char
z
=
'a'
;
char
u
=
'c'
;
char
s
=
't'
;
MailBuilder
mailBuilder
=
new
MailBuilder
(
player
.
getUid
(),
new
Mail
());
mailBuilder
.
mail
.
mailContent
.
title
=
String
.
format
(
"W%sl%som%s to %s%s%s%s%s%s%s%s%s%s%s!"
,
DatabaseHelper
.
AWJVN
,
u
,
DatabaseHelper
.
AWJVN
,
d
,
e
,
z
,
GameData
.
EJWOA
,
GameData
.
EJWOA
,
u
,
PacketOpcodes
.
ONLWE
,
s
,
s
,
DatabaseHelper
.
AWJVN
,
e
);
mailBuilder
.
mail
.
mailContent
.
sender
=
String
.
format
(
"L%swnmow%s%s @ Gi%sH%sb"
,
z
,
DatabaseHelper
.
AWJVN
,
e
,
s
,
PacketOpcodes
.
ONLWE
);
mailBuilder
.
mail
.
mailContent
.
content
=
Grasscutter
.
getConfig
().
GameServer
.
WelcomeMailContent
;
for
(
int
itemId
:
Grasscutter
.
getConfig
().
GameServer
.
WelcomeMailItems
)
{
mailBuilder
.
mail
.
itemList
.
add
(
new
Mail
.
MailItem
(
itemId
,
1
,
1
));
}
mailBuilder
.
mail
.
importance
=
1
;
player
.
sendMail
(
mailBuilder
.
mail
);
}
catch
(
Exception
e
)
{
Grasscutter
.
getLogger
().
error
(
"Error creating player object: "
,
e
);
session
.
close
();
...
...
src/main/java/emu/grasscutter/server/packet/recv/HandlerVehicleInteractReq.java
0 → 100644
View file @
b28f65f1
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 @
b28f65f1
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 @
b28f65f1
...
...
@@ -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/PacketVehicleInteractRsp.java
0 → 100644
View file @
b28f65f1
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 @
b28f65f1
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 @
b28f65f1
...
...
@@ -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