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
6554c37d
Commit
6554c37d
authored
Apr 23, 2022
by
WangYneos
Committed by
GitHub
Apr 23, 2022
Browse files
Merge branch 'development' into stable
parents
39e590df
df1dca8d
Changes
39
Show whitespace changes
Inline
Side-by-side
.gitignore
View file @
6554c37d
...
...
@@ -47,6 +47,7 @@ tmp/
# Grasscutter
resources/*
logs/*
data/AbilityEmbryos.json
data/OpenConfig.json
proto/auto/
...
...
README.md
View file @
6554c37d
...
...
@@ -16,7 +16,7 @@ A WIP server reimplementation for *some anime game* 2.3-2.6
*
If you update from an older version, delete
`config.json`
for regeneration
### Prerequisites
*
J
DK-8u202 (
[
mirror link
](
https://mirrors.huaweicloud.com/java/jdk/8u202-b08/
)
since Oracle required an account to download old builds)
*
J
ava 16
*
Mongodb (recommended 4.0+)
*
Proxy daemon: mitmproxy (mitmdump, recommended), Fiddler Classic, etc.
...
...
build.gradle
View file @
6554c37d
...
...
@@ -14,12 +14,11 @@ plugins {
id
'application'
}
sourceCompatibility
=
1
.8
targetCompatibility
=
1
.8
sourceCompatibility
=
1
6
targetCompatibility
=
1
6
repositories
{
mavenCentral
()
jcenter
()
}
dependencies
{
...
...
@@ -33,9 +32,9 @@ dependencies {
implementation
group:
'com.google.code.gson'
,
name:
'gson'
,
version:
'2.8.8'
implementation
group:
'com.google.protobuf'
,
name:
'protobuf-java'
,
version:
'3.18.1'
implementation
group:
'org.reflections'
,
name:
'reflections'
,
version:
'0.
9.1
2'
implementation
group:
'org.reflections'
,
name:
'reflections'
,
version:
'0.
10.
2'
implementation
group:
'dev.morphia.morphia'
,
name:
'core'
,
version:
'
1.6.1
'
implementation
group:
'dev.morphia.morphia'
,
name:
'
morphia-
core'
,
version:
'
2.2.6
'
implementation
group:
'org.greenrobot'
,
name:
'eventbus-java'
,
version:
'3.3.1'
}
...
...
keystore.p12
View file @
6554c37d
No preview for this file type
proxy.py
View file @
6554c37d
...
...
@@ -57,7 +57,9 @@ class MlgmXyysd_Genshin_Impact_Proxy:
"minor-api.mihoyo.com"
,
"public-data-api.mihoyo.com"
,
"uspider.yuanshen.com"
,
"sdk-static.mihoyo.com"
"sdk-static.mihoyo.com"
,
"abtest-api-data-sg.hoyoverse.com"
,
"log-upload-os.hoyoverse.com"
]
def
request
(
self
,
flow
:
http
.
HTTPFlow
)
->
None
:
...
...
src/main/java/emu/grasscutter/Config.java
View file @
6554c37d
...
...
@@ -27,9 +27,11 @@ public final class Config {
public
String
Ip
=
"0.0.0.0"
;
public
String
PublicIp
=
"127.0.0.1"
;
public
int
Port
=
443
;
public
int
PublicPort
=
0
;
public
String
KeystorePath
=
"./keystore.p12"
;
public
String
KeystorePassword
=
""
;
public
String
KeystorePassword
=
"
123456
"
;
public
Boolean
UseSSL
=
true
;
public
Boolean
FrontHTTPS
=
true
;
public
boolean
AutomaticallyCreateAccounts
=
false
;
...
...
@@ -52,6 +54,7 @@ public final class Config {
public
String
Ip
=
"0.0.0.0"
;
public
String
PublicIp
=
"127.0.0.1"
;
public
int
Port
=
22102
;
public
int
PublicPort
=
0
;
public
String
DispatchServerDatabaseUrl
=
"mongodb://localhost:27017"
;
public
String
DispatchServerDatabaseCollection
=
"grasscutter"
;
...
...
src/main/java/emu/grasscutter/Grasscutter.java
View file @
6554c37d
...
...
@@ -34,7 +34,7 @@ public final class Grasscutter {
private
static
DispatchServer
dispatchServer
;
private
static
GameServer
gameServer
;
public
static
final
Reflections
reflector
=
new
Reflections
();
public
static
final
Reflections
reflector
=
new
Reflections
(
"emu.grasscutter"
);
static
{
// Declare logback configuration.
...
...
src/main/java/emu/grasscutter/command/CommandMap.java
View file @
6554c37d
...
...
@@ -11,6 +11,7 @@ import java.util.*;
public
final
class
CommandMap
{
private
final
Map
<
String
,
CommandHandler
>
commands
=
new
HashMap
<>();
private
final
Map
<
String
,
Command
>
annotations
=
new
HashMap
<>();
public
CommandMap
()
{
this
(
false
);
}
...
...
src/main/java/emu/grasscutter/command/commands/ClearWeaponsCommand.java
0 → 100644
View file @
6554c37d
package
emu.grasscutter.command.commands
;
import
emu.grasscutter.command.Command
;
import
emu.grasscutter.command.CommandHandler
;
import
emu.grasscutter.game.GenshinPlayer
;
import
emu.grasscutter.game.inventory.Inventory
;
import
emu.grasscutter.game.inventory.ItemType
;
import
java.util.List
;
@Command
(
label
=
"clearweapons"
,
usage
=
"clearweapons"
,
description
=
"Deletes all unequipped and unlocked weapons, including yellow rarity ones from your inventory"
,
aliases
=
{
"clearwpns"
},
permission
=
"player.clearweapons"
)
public
final
class
ClearWeaponsCommand
implements
CommandHandler
{
@Override
public
void
execute
(
GenshinPlayer
sender
,
List
<
String
>
args
)
{
if
(
sender
==
null
)
{
CommandHandler
.
sendMessage
(
null
,
"Run this command in-game."
);
return
;
// TODO: clear player's weapons from console or other players
}
Inventory
playerInventory
=
sender
.
getInventory
();
playerInventory
.
getItems
().
values
().
stream
()
.
filter
(
item
->
item
.
getItemType
()
==
ItemType
.
ITEM_WEAPON
)
.
filter
(
item
->
!
item
.
isLocked
()
&&
!
item
.
isEquipped
())
.
forEach
(
item
->
playerInventory
.
removeItem
(
item
,
item
.
getCount
()));
}
}
src/main/java/emu/grasscutter/command/commands/TalentCommand.java
0 → 100644
View file @
6554c37d
package
emu.grasscutter.command.commands
;
import
emu.grasscutter.command.Command
;
import
emu.grasscutter.command.CommandHandler
;
import
emu.grasscutter.game.GenshinPlayer
;
import
emu.grasscutter.game.avatar.GenshinAvatar
;
import
emu.grasscutter.game.entity.EntityAvatar
;
import
emu.grasscutter.server.packet.send.PacketAvatarSkillChangeNotify
;
import
emu.grasscutter.server.packet.send.PacketAvatarSkillUpgradeRsp
;
import
java.util.List
;
@Command
(
label
=
"talent"
,
usage
=
"talent <talentID> <value>"
,
description
=
"Set talent level for your current active character"
,
permission
=
"player.settalent"
)
public
class
TalentCommand
implements
CommandHandler
{
@Override
public
void
execute
(
GenshinPlayer
sender
,
List
<
String
>
args
)
{
if
(
sender
==
null
)
{
CommandHandler
.
sendMessage
(
null
,
"Run this command in-game."
);
return
;
}
if
(
args
.
size
()
<
0
||
args
.
size
()
<
1
){
CommandHandler
.
sendMessage
(
sender
,
"To set talent level: /talent set <talentID> <value>"
);
CommandHandler
.
sendMessage
(
sender
,
"To get talent ID: /talent getid"
);
return
;
}
String
cmdSwitch
=
args
.
get
(
0
);
switch
(
cmdSwitch
)
{
default
:
CommandHandler
.
sendMessage
(
sender
,
"To set talent level: /talent set <talentID> <value>"
);
CommandHandler
.
sendMessage
(
sender
,
"To get talent ID: /talent getid"
);
return
;
case
"set"
:
try
{
int
skillId
=
Integer
.
parseInt
(
args
.
get
(
1
));
int
nextLevel
=
Integer
.
parseInt
(
args
.
get
(
2
));
EntityAvatar
entity
=
sender
.
getTeamManager
().
getCurrentAvatarEntity
();
GenshinAvatar
avatar
=
entity
.
getAvatar
();
int
skillIdNorAtk
=
avatar
.
getData
().
getSkillDepot
().
getSkills
().
get
(
0
);
int
skillIdE
=
avatar
.
getData
().
getSkillDepot
().
getSkills
().
get
(
1
);
int
skillIdQ
=
avatar
.
getData
().
getSkillDepot
().
getEnergySkill
();
int
currentLevelNorAtk
=
avatar
.
getSkillLevelMap
().
get
(
skillIdNorAtk
);
int
currentLevelE
=
avatar
.
getSkillLevelMap
().
get
(
skillIdE
);
int
currentLevelQ
=
avatar
.
getSkillLevelMap
().
get
(
skillIdQ
);
if
(
args
.
size
()
<
2
){
CommandHandler
.
sendMessage
(
sender
,
"To set talent level: /talent set <talentID> <value>"
);
CommandHandler
.
sendMessage
(
sender
,
"To get talent ID: /talent getid"
);
return
;
}
if
(
nextLevel
>
16
){
CommandHandler
.
sendMessage
(
sender
,
"Invalid talent level. Level should be lower than 16"
);
return
;
}
if
(
skillId
==
skillIdNorAtk
){
// Upgrade skill
avatar
.
getSkillLevelMap
().
put
(
skillIdNorAtk
,
nextLevel
);
avatar
.
save
();
// Packet
sender
.
sendPacket
(
new
PacketAvatarSkillChangeNotify
(
avatar
,
skillIdNorAtk
,
currentLevelNorAtk
,
nextLevel
));
sender
.
sendPacket
(
new
PacketAvatarSkillUpgradeRsp
(
avatar
,
skillIdNorAtk
,
currentLevelNorAtk
,
nextLevel
));
CommandHandler
.
sendMessage
(
sender
,
"Set talent Normal ATK to "
+
nextLevel
+
"."
);
}
if
(
skillId
==
skillIdE
){
// Upgrade skill
avatar
.
getSkillLevelMap
().
put
(
skillIdE
,
nextLevel
);
avatar
.
save
();
// Packet
sender
.
sendPacket
(
new
PacketAvatarSkillChangeNotify
(
avatar
,
skillIdE
,
currentLevelE
,
nextLevel
));
sender
.
sendPacket
(
new
PacketAvatarSkillUpgradeRsp
(
avatar
,
skillIdE
,
currentLevelE
,
nextLevel
));
CommandHandler
.
sendMessage
(
sender
,
"Set talent E to "
+
nextLevel
+
"."
);
}
if
(
skillId
==
skillIdQ
){
// Upgrade skill
avatar
.
getSkillLevelMap
().
put
(
skillIdQ
,
nextLevel
);
avatar
.
save
();
// Packet
sender
.
sendPacket
(
new
PacketAvatarSkillChangeNotify
(
avatar
,
skillIdQ
,
currentLevelQ
,
nextLevel
));
sender
.
sendPacket
(
new
PacketAvatarSkillUpgradeRsp
(
avatar
,
skillIdQ
,
currentLevelQ
,
nextLevel
));
CommandHandler
.
sendMessage
(
sender
,
"Set talent Q to "
+
nextLevel
+
"."
);
}
}
catch
(
NumberFormatException
ignored
)
{
CommandHandler
.
sendMessage
(
sender
,
"Invalid skill ID."
);
return
;
}
break
;
case
"getid"
:
EntityAvatar
entity
=
sender
.
getTeamManager
().
getCurrentAvatarEntity
();
GenshinAvatar
avatar
=
entity
.
getAvatar
();
int
skillIdNorAtk
=
avatar
.
getData
().
getSkillDepot
().
getSkills
().
get
(
0
);
int
skillIdE
=
avatar
.
getData
().
getSkillDepot
().
getSkills
().
get
(
1
);
int
skillIdQ
=
avatar
.
getData
().
getSkillDepot
().
getEnergySkill
();
CommandHandler
.
sendMessage
(
sender
,
"Normal Attack ID "
+
skillIdNorAtk
+
"."
);
CommandHandler
.
sendMessage
(
sender
,
"E skill ID "
+
skillIdE
+
"."
);
CommandHandler
.
sendMessage
(
sender
,
"Q skill ID "
+
skillIdQ
+
"."
);
break
;
}
}
}
src/main/java/emu/grasscutter/database/DatabaseCounter.java
View file @
6554c37d
...
...
@@ -3,7 +3,7 @@ package emu.grasscutter.database;
import
dev.morphia.annotations.Entity
;
import
dev.morphia.annotations.Id
;
@Entity
(
value
=
"counters"
,
noClassnameS
tor
ed
=
tru
e
)
@Entity
(
value
=
"counters"
,
useDiscrimina
tor
=
fals
e
)
public
class
DatabaseCounter
{
@Id
private
String
id
;
...
...
src/main/java/emu/grasscutter/database/DatabaseHelper.java
View file @
6554c37d
...
...
@@ -2,23 +2,16 @@ package emu.grasscutter.database;
import
java.util.List
;
import
com.mongodb.WriteResult
;
import
dev.morphia.query.FindOptions
;
import
dev.morphia.query.Query
;
import
dev.morphia.query.internal.MorphiaCursor
;
import
com.mongodb.client.result.DeleteResult
;
import
dev.morphia.query.experimental.filters.Filters
;
import
emu.grasscutter.GenshinConstants
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.game.Account
;
import
emu.grasscutter.game.GenshinPlayer
;
import
emu.grasscutter.game.avatar.GenshinAvatar
;
import
emu.grasscutter.game.friends.Friendship
;
import
emu.grasscutter.game.inventory.GenshinItem
;
public
class
DatabaseHelper
{
protected
static
FindOptions
FIND_ONE
=
new
FindOptions
().
limit
(
1
);
public
final
class
DatabaseHelper
{
public
static
Account
createAccount
(
String
username
)
{
return
createAccountWithId
(
username
,
0
);
}
...
...
@@ -36,7 +29,6 @@ public class DatabaseHelper {
if
(
reservedId
==
GenshinConstants
.
SERVER_CONSOLE_UID
)
{
return
null
;
}
exists
=
DatabaseHelper
.
getAccountByPlayerId
(
reservedId
);
if
(
exists
!=
null
)
{
return
null
;
...
...
@@ -78,50 +70,37 @@ public class DatabaseHelper {
}
public
static
Account
getAccountByName
(
String
username
)
{
MorphiaCursor
<
Account
>
cursor
=
DatabaseManager
.
getAccountDatastore
().
createQuery
(
Account
.
class
).
field
(
"username"
).
equalIgnoreCase
(
username
).
find
(
FIND_ONE
);
if
(!
cursor
.
hasNext
())
return
null
;
return
cursor
.
next
();
return
DatabaseManager
.
getDatastore
().
find
(
Account
.
class
).
filter
(
Filters
.
eq
(
"username"
,
username
)).
first
();
}
public
static
Account
getAccountByToken
(
String
token
)
{
if
(
token
==
null
)
return
null
;
MorphiaCursor
<
Account
>
cursor
=
DatabaseManager
.
getAccountDatastore
().
createQuery
(
Account
.
class
).
field
(
"token"
).
equal
(
token
).
find
(
FIND_ONE
);
if
(!
cursor
.
hasNext
())
return
null
;
return
cursor
.
next
();
if
(
token
==
null
)
return
null
;
return
DatabaseManager
.
getDatastore
().
find
(
Account
.
class
).
filter
(
Filters
.
eq
(
"token"
,
token
)).
first
();
}
public
static
Account
getAccountById
(
String
uid
)
{
MorphiaCursor
<
Account
>
cursor
=
DatabaseManager
.
getAccountDatastore
().
createQuery
(
Account
.
class
).
field
(
"_id"
).
equal
(
uid
).
find
(
FIND_ONE
);
if
(!
cursor
.
hasNext
())
return
null
;
return
cursor
.
next
();
return
DatabaseManager
.
getDatastore
().
find
(
Account
.
class
).
filter
(
Filters
.
eq
(
"_id"
,
uid
)).
first
();
}
public
static
Account
getAccountByPlayerId
(
int
playerId
)
{
MorphiaCursor
<
Account
>
cursor
=
DatabaseManager
.
getAccountDatastore
().
createQuery
(
Account
.
class
).
field
(
"playerId"
).
equal
(
playerId
).
find
(
FIND_ONE
);
if
(!
cursor
.
hasNext
())
return
null
;
return
cursor
.
next
();
return
DatabaseManager
.
getDatastore
().
find
(
Account
.
class
).
filter
(
Filters
.
eq
(
"playerId"
,
playerId
)).
first
();
}
public
static
boolean
deleteAccount
(
String
username
)
{
Query
<
Account
>
q
=
DatabaseManager
.
getAccountDatastore
().
createQuery
(
Account
.
class
).
field
(
"username"
).
equalIgnoreCase
(
username
);
return
DatabaseManager
.
getDatastore
().
findAndDelete
(
q
)
!=
null
;
return
DatabaseManager
.
getDatastore
().
find
(
Account
.
class
).
filter
(
Filters
.
eq
(
"username"
,
username
)).
delete
().
getDeletedCount
()
>
0
;
}
public
static
GenshinPlayer
getPlayerById
(
int
id
)
{
Query
<
GenshinPlayer
>
query
=
DatabaseManager
.
getDatastore
().
createQuery
(
GenshinPlayer
.
class
).
field
(
"_id"
).
equal
(
id
);
MorphiaCursor
<
GenshinPlayer
>
cursor
=
query
.
find
(
FIND_ONE
);
if
(!
cursor
.
hasNext
())
return
null
;
return
cursor
.
next
();
return
DatabaseManager
.
getDatastore
().
find
(
GenshinPlayer
.
class
).
filter
(
Filters
.
eq
(
"_id"
,
id
)).
first
();
}
public
static
boolean
checkPlayerExists
(
int
id
)
{
MorphiaCursor
<
GenshinPlayer
>
query
=
DatabaseManager
.
getDatastore
().
createQuery
(
GenshinPlayer
.
class
).
field
(
"_id"
).
equal
(
id
).
find
(
FIND_ONE
);
return
query
.
hasNext
();
return
DatabaseManager
.
getDatastore
().
find
(
GenshinPlayer
.
class
).
filter
(
Filters
.
eq
(
"_id"
,
id
)).
first
()
!=
null
;
}
public
static
synchronized
GenshinPlayer
createPlayer
(
GenshinPlayer
character
,
int
reservedId
)
{
// Check if reserved id
int
id
=
0
;
int
id
;
if
(
reservedId
>
0
&&
!
checkPlayerExists
(
reservedId
))
{
id
=
reservedId
;
character
.
setUid
(
id
);
...
...
@@ -139,7 +118,7 @@ public class DatabaseHelper {
public
static
synchronized
int
getNextPlayerId
(
int
reservedId
)
{
// Check if reserved id
int
id
=
0
;
int
id
;
if
(
reservedId
>
0
&&
!
checkPlayerExists
(
reservedId
))
{
id
=
reservedId
;
}
else
{
...
...
@@ -160,8 +139,7 @@ public class DatabaseHelper {
}
public
static
List
<
GenshinAvatar
>
getAvatars
(
GenshinPlayer
player
)
{
Query
<
GenshinAvatar
>
query
=
DatabaseManager
.
getDatastore
().
createQuery
(
GenshinAvatar
.
class
).
filter
(
"ownerId"
,
player
.
getUid
());
return
query
.
find
().
toList
();
return
DatabaseManager
.
getDatastore
().
find
(
GenshinAvatar
.
class
).
filter
(
Filters
.
eq
(
"ownerId"
,
player
.
getUid
())).
stream
().
toList
();
}
public
static
void
saveItem
(
GenshinItem
item
)
{
...
...
@@ -169,22 +147,19 @@ public class DatabaseHelper {
}
public
static
boolean
deleteItem
(
GenshinItem
item
)
{
Wri
teResult
result
=
DatabaseManager
.
getDatastore
().
delete
(
item
);
Dele
teResult
result
=
DatabaseManager
.
getDatastore
().
delete
(
item
);
return
result
.
wasAcknowledged
();
}
public
static
List
<
GenshinItem
>
getInventoryItems
(
GenshinPlayer
player
)
{
Query
<
GenshinItem
>
query
=
DatabaseManager
.
getDatastore
().
createQuery
(
GenshinItem
.
class
).
filter
(
"ownerId"
,
player
.
getUid
());
return
query
.
find
().
toList
();
return
DatabaseManager
.
getDatastore
().
find
(
GenshinItem
.
class
).
filter
(
Filters
.
eq
(
"ownerId"
,
player
.
getUid
())).
stream
().
toList
();
}
public
static
List
<
Friendship
>
getFriends
(
GenshinPlayer
player
)
{
Query
<
Friendship
>
query
=
DatabaseManager
.
getDatastore
().
createQuery
(
Friendship
.
class
).
filter
(
"ownerId"
,
player
.
getUid
());
return
query
.
find
().
toList
();
return
DatabaseManager
.
getDatastore
().
find
(
Friendship
.
class
).
filter
(
Filters
.
eq
(
"ownerId"
,
player
.
getUid
())).
stream
().
toList
();
}
public
static
List
<
Friendship
>
getReverseFriends
(
GenshinPlayer
player
)
{
Query
<
Friendship
>
query
=
DatabaseManager
.
getDatastore
().
createQuery
(
Friendship
.
class
).
filter
(
"friendId"
,
player
.
getUid
());
return
query
.
find
().
toList
();
return
DatabaseManager
.
getDatastore
().
find
(
Friendship
.
class
).
filter
(
Filters
.
eq
(
"friendId"
,
player
.
getUid
())).
stream
().
toList
();
}
public
static
void
saveFriendship
(
Friendship
friendship
)
{
...
...
@@ -196,13 +171,9 @@ public class DatabaseHelper {
}
public
static
Friendship
getReverseFriendship
(
Friendship
friendship
)
{
Query
<
Friendship
>
query
=
DatabaseManager
.
getDatastore
().
createQuery
(
Friendship
.
class
);
query
.
and
(
query
.
criteria
(
"ownerId"
).
equal
(
friendship
.
getFriendId
()),
query
.
criteria
(
"friendId"
).
equal
(
friendship
.
getOwnerId
())
);
MorphiaCursor
<
Friendship
>
reverseFriendship
=
query
.
find
(
FIND_ONE
);
if
(!
reverseFriendship
.
hasNext
())
return
null
;
return
reverseFriendship
.
next
();
return
DatabaseManager
.
getDatastore
().
find
(
Friendship
.
class
).
filter
(
Filters
.
and
(
Filters
.
eq
(
"ownerId"
,
friendship
.
getFriendId
()),
Filters
.
eq
(
"friendId"
,
friendship
.
getOwnerId
())
)).
first
();
}
}
src/main/java/emu/grasscutter/database/DatabaseManager.java
View file @
6554c37d
package
emu.grasscutter.database
;
import
com.mongodb.MongoClient
;
import
com.mongodb.MongoClientURI
;
import
com.mongodb.MongoCommandException
;
import
com.mongodb.client.MongoClient
;
import
com.mongodb.client.MongoClients
;
import
com.mongodb.client.MongoDatabase
;
import
com.mongodb.client.MongoIterable
;
import
dev.morphia.Datastore
;
import
dev.morphia.Morphia
;
import
dev.morphia.mapping.MapperOptions
;
import
dev.morphia.query.experimental.filters.Filters
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.game.Account
;
import
emu.grasscutter.game.GenshinPlayer
;
...
...
@@ -16,6 +19,7 @@ import emu.grasscutter.game.friends.Friendship;
import
emu.grasscutter.game.inventory.GenshinItem
;
public
final
class
DatabaseManager
{
private
static
MongoClient
mongoClient
;
private
static
MongoClient
dispatchMongoClient
;
...
...
@@ -26,10 +30,6 @@ public final class DatabaseManager {
DatabaseCounter
.
class
,
Account
.
class
,
GenshinPlayer
.
class
,
GenshinAvatar
.
class
,
GenshinItem
.
class
,
Friendship
.
class
};
public
static
MongoClient
getMongoClient
()
{
return
mongoClient
;
}
public
static
Datastore
getDatastore
()
{
return
datastore
;
}
...
...
@@ -50,27 +50,23 @@ public final class DatabaseManager {
public
static
void
initialize
()
{
// Initialize
mongoClient
=
new
MongoClient
(
new
MongoClientURI
(
Grasscutter
.
getConfig
().
DatabaseUrl
));
Morphia
morphia
=
new
Morphia
();
// TODO Update when migrating to Morphia 2.0
morphia
.
getMapper
().
getOptions
().
setStoreEmpties
(
true
);
morphia
.
getMapper
().
getOptions
().
setStoreNulls
(
false
);
morphia
.
getMapper
().
getOptions
().
setDisableEmbeddedIndexes
(
true
);
MongoClient
mongoClient
=
MongoClients
.
create
(
Grasscutter
.
getConfig
().
DatabaseUrl
);
// Map
morphia
.
map
(
mappedClasses
);
// Build datastore
datastore
=
morphia
.
createDatastore
(
mongoClient
,
Grasscutter
.
getConfig
().
DatabaseCollection
);
// Set mapper options.
MapperOptions
mapperOptions
=
MapperOptions
.
builder
()
.
storeEmpties
(
true
).
storeNulls
(
false
).
build
();
// Create data store.
datastore
=
Morphia
.
createDatastore
(
mongoClient
,
Grasscutter
.
getConfig
().
DatabaseCollection
,
mapperOptions
);
// Map classes.
datastore
.
getMapper
().
map
(
mappedClasses
);
// Ensure indexes
try
{
datastore
.
ensureIndexes
();
}
catch
(
MongoCommandException
e
)
{
Grasscutter
.
getLogger
().
info
(
"Mongo index error: "
,
e
);
}
catch
(
MongoCommandException
e
xception
)
{
Grasscutter
.
getLogger
().
info
(
"Mongo index error: "
,
e
xception
);
// Duplicate index error
if
(
e
.
getCode
()
==
85
)
{
if
(
e
xception
.
getCode
()
==
85
)
{
// Drop all indexes and re add them
MongoIterable
<
String
>
collections
=
datastore
.
getDatabase
().
listCollectionNames
();
for
(
String
name
:
collections
)
{
...
...
@@ -82,8 +78,8 @@ public final class DatabaseManager {
}
if
(
Grasscutter
.
getConfig
().
RunMode
.
equalsIgnoreCase
(
"GAME_ONLY"
))
{
dispatchMongoClient
=
new
MongoClient
(
new
MongoClientURI
(
Grasscutter
.
getConfig
().
getGameServerOptions
().
DispatchServerDatabaseUrl
)
)
;
dispatchDatastore
=
m
orphia
.
createDatastore
(
dispatchMongoClient
,
Grasscutter
.
getConfig
().
getGameServerOptions
().
DispatchServerDatabaseCollection
);
dispatchMongoClient
=
MongoClient
s
.
create
(
Grasscutter
.
getConfig
().
getGameServerOptions
().
DispatchServerDatabaseUrl
);
dispatchDatastore
=
M
orphia
.
createDatastore
(
dispatchMongoClient
,
Grasscutter
.
getConfig
().
getGameServerOptions
().
DispatchServerDatabaseCollection
);
// Ensure indexes for dispatch server
try
{
...
...
@@ -105,7 +101,7 @@ public final class DatabaseManager {
}
public
static
synchronized
int
getNextId
(
Class
<?>
c
)
{
DatabaseCounter
counter
=
getDatastore
().
createQuery
(
DatabaseCounter
.
class
).
fi
eld
(
"_id"
).
equal
(
c
.
getSimple
Name
()).
fi
nd
().
tryNex
t
();
DatabaseCounter
counter
=
getDatastore
().
find
(
DatabaseCounter
.
class
).
fi
lter
(
Filters
.
eq
(
"_id"
,
c
.
get
Name
())
)
.
fi
rs
t
();
if
(
counter
==
null
)
{
counter
=
new
DatabaseCounter
(
c
.
getSimpleName
());
}
...
...
src/main/java/emu/grasscutter/game/Account.java
View file @
6554c37d
package
emu.grasscutter.game
;
import
dev.morphia.annotations.AlsoLoad
;
import
dev.morphia.annotations.Collation
;
import
dev.morphia.annotations.Entity
;
import
dev.morphia.annotations.Id
;
import
dev.morphia.annotations.Indexed
;
import
dev.morphia.annotations.PreLoad
;
import
dev.morphia.annotations.*
;
import
emu.grasscutter.database.DatabaseHelper
;
import
emu.grasscutter.utils.Crypto
;
import
emu.grasscutter.utils.Utils
;
import
dev.morphia.annotations.IndexOptions
;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.bson.Document
;
import
com.mongodb.DBObject
;
@Entity
(
value
=
"accounts"
,
noClassnameS
tor
ed
=
tru
e
)
@Entity
(
value
=
"accounts"
,
useDiscrimina
tor
=
fals
e
)
public
class
Account
{
@Id
private
String
id
;
...
...
@@ -122,15 +118,15 @@ public class Account {
return
this
.
token
;
}
public
void
save
()
{
DatabaseHelper
.
saveAccount
(
this
);
}
@PreLoad
public
void
onLoad
(
D
BObject
dbObj
)
{
public
void
onLoad
(
D
ocument
document
)
{
// Grant the superuser permissions to accounts created before the permissions update
if
(!
d
bObj
.
contains
Field
(
"permissions"
))
{
if
(!
d
ocument
.
contains
Key
(
"permissions"
))
{
this
.
addPermission
(
"*"
);
}
}
public
void
save
()
{
DatabaseHelper
.
saveAccount
(
this
);
}
}
src/main/java/emu/grasscutter/game/GenshinPlayer.java
View file @
6554c37d
...
...
@@ -18,6 +18,7 @@ import emu.grasscutter.game.friends.PlayerProfile;
import
emu.grasscutter.game.gacha.PlayerGachaInfo
;
import
emu.grasscutter.game.inventory.GenshinItem
;
import
emu.grasscutter.game.inventory.Inventory
;
import
emu.grasscutter.game.player.PlayerBirthday
;
import
emu.grasscutter.game.props.ActionReason
;
import
emu.grasscutter.game.props.PlayerProperty
;
import
emu.grasscutter.net.packet.GenshinPacket
;
...
...
@@ -61,7 +62,7 @@ import emu.grasscutter.utils.Position;
import
it.unimi.dsi.fastutil.ints.Int2ObjectMap
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
;
@Entity
(
value
=
"players"
,
noClassnameS
tor
ed
=
tru
e
)
@Entity
(
value
=
"players"
,
useDiscrimina
tor
=
fals
e
)
public
class
GenshinPlayer
{
@Id
private
int
id
;
@Indexed
(
options
=
@IndexOptions
(
unique
=
true
))
private
String
accountId
;
...
...
@@ -73,6 +74,7 @@ public class GenshinPlayer {
private
int
nameCardId
=
210001
;
private
Position
pos
;
private
Position
rotation
;
private
PlayerBirthday
birthday
;
private
Map
<
Integer
,
Integer
>
properties
;
private
Set
<
Integer
>
nameCardList
;
...
...
@@ -139,6 +141,8 @@ public class GenshinPlayer {
this
.
combatInvokeHandler
=
new
InvokeHandler
(
PacketCombatInvocationsNotify
.
class
);
this
.
abilityInvokeHandler
=
new
InvokeHandler
(
PacketAbilityInvocationsNotify
.
class
);
this
.
clientAbilityInitFinishHandler
=
new
InvokeHandler
(
PacketClientAbilityInitFinishNotify
.
class
);
this
.
birthday
=
new
PlayerBirthday
();
}
// On player creation
...
...
@@ -150,6 +154,7 @@ public class GenshinPlayer {
this
.
nickname
=
"Traveler"
;
this
.
signature
=
""
;
this
.
teamManager
=
new
TeamManager
(
this
);
this
.
birthday
=
new
PlayerBirthday
();
this
.
setProperty
(
PlayerProperty
.
PROP_PLAYER_LEVEL
,
1
);
this
.
setProperty
(
PlayerProperty
.
PROP_IS_SPRING_AUTO_USE
,
1
);
this
.
setProperty
(
PlayerProperty
.
PROP_SPRING_AUTO_USE_PERCENT
,
50
);
...
...
@@ -642,6 +647,15 @@ public class GenshinPlayer {
return
onlineInfo
.
build
();
}
public
PlayerBirthday
getBirthday
(){
return
this
.
birthday
;
}
public
void
setBirthday
(
int
d
,
int
m
)
{
this
.
birthday
=
new
PlayerBirthday
(
d
,
m
);
this
.
updateProfile
();
}
public
SocialDetail
.
Builder
getSocialDetail
()
{
SocialDetail
.
Builder
social
=
SocialDetail
.
newBuilder
()
.
setUid
(
this
.
getUid
())
...
...
@@ -649,7 +663,7 @@ public class GenshinPlayer {
.
setNickname
(
this
.
getNickname
())
.
setSignature
(
this
.
getSignature
())
.
setLevel
(
this
.
getLevel
())
.
setBirthday
(
Birthday
.
newBuilder
())
.
setBirthday
(
this
.
getBirthday
().
getFilledProtoWhenNotEmpty
())
.
setWorldLevel
(
this
.
getWorldLevel
())
.
setUnk1
(
1
)
.
setUnk3
(
1
)
...
...
src/main/java/emu/grasscutter/game/TeamInfo.java
View file @
6554c37d
...
...
@@ -3,10 +3,12 @@ package emu.grasscutter.game;
import
java.util.ArrayList
;
import
java.util.List
;
import
dev.morphia.annotations.Entity
;
import
emu.grasscutter.GenshinConstants
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.game.avatar.GenshinAvatar
;
@Entity
public
class
TeamInfo
{
private
String
name
;
private
List
<
Integer
>
avatars
;
...
...
src/main/java/emu/grasscutter/game/TeamManager.java
View file @
6554c37d
...
...
@@ -8,6 +8,7 @@ import java.util.List;
import
java.util.Map
;
import
java.util.Set
;
import
dev.morphia.annotations.Entity
;
import
dev.morphia.annotations.Transient
;
import
emu.grasscutter.GenshinConstants
;
import
emu.grasscutter.Grasscutter
;
...
...
@@ -41,6 +42,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import
it.unimi.dsi.fastutil.ints.IntOpenHashSet
;
import
it.unimi.dsi.fastutil.ints.IntSet
;
@Entity
public
class
TeamManager
{
@Transient
private
GenshinPlayer
player
;
...
...
src/main/java/emu/grasscutter/game/avatar/AvatarProfileData.java
View file @
6554c37d
package
emu.grasscutter.game.avatar
;
import
dev.morphia.annotations.Entity
;
@Entity
public
class
AvatarProfileData
{
private
int
avatarId
;
private
int
level
;
...
...
src/main/java/emu/grasscutter/game/avatar/GenshinAvatar.java
View file @
6554c37d
...
...
@@ -56,7 +56,7 @@ import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap;
import
it.unimi.dsi.fastutil.ints.Int2ObjectMap
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap
;
@Entity
(
value
=
"avatars"
,
noClassnameS
tor
ed
=
tru
e
)
@Entity
(
value
=
"avatars"
,
useDiscrimina
tor
=
fals
e
)
public
class
GenshinAvatar
{
@Id
private
ObjectId
id
;
@Indexed
private
int
ownerId
;
// Id of player that this avatar belongs to
...
...
src/main/java/emu/grasscutter/game/friends/Friendship.java
View file @
6554c37d
...
...
@@ -9,7 +9,7 @@ import emu.grasscutter.net.proto.FriendBriefOuterClass.FriendBrief;
import
emu.grasscutter.net.proto.FriendOnlineStateOuterClass.FriendOnlineState
;
import
emu.grasscutter.net.proto.HeadImageOuterClass.HeadImage
;
@Entity
(
value
=
"friendships"
,
noClassnameS
tor
ed
=
tru
e
)
@Entity
(
value
=
"friendships"
,
useDiscrimina
tor
=
fals
e
)
public
class
Friendship
{
@Id
private
ObjectId
id
;
...
...
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