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
11161227
Commit
11161227
authored
May 11, 2022
by
KingRainbow44
Browse files
Convert to the far superior config system
parent
c274907e
Changes
39
Show whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/Configuration.java
View file @
11161227
...
...
@@ -3,17 +3,141 @@ package emu.grasscutter;
import
emu.grasscutter.Grasscutter.*
;
import
emu.grasscutter.game.mail.Mail.*
;
import
java.lang.reflect.Field
;
import
java.util.Arrays
;
import
java.util.Locale
;
import
static
emu
.
grasscutter
.
Grasscutter
.
config
;
/**
* A data container for the server's configuration.
*
* Use `import static emu.grasscutter.Configuration.*;`
* to import all configuration constants.
*/
public
final
class
Configuration
{
private
static
int
version
()
{
return
1
;
}
/**
* Attempts to update the server's existing configuration to the latest configuration.
*/
public
static
void
updateConfig
()
{
var
existing
=
config
.
version
;
var
latest
=
version
();
if
(
existing
==
latest
)
return
;
// Create a new configuration instance.
Configuration
updated
=
new
Configuration
();
// Update all configuration fields.
Field
[]
fields
=
Configuration
.
class
.
getDeclaredFields
();
Arrays
.
stream
(
fields
).
forEach
(
field
->
{
try
{
field
.
set
(
updated
,
field
.
get
(
config
));
}
catch
(
Exception
exception
)
{
Grasscutter
.
getLogger
().
error
(
"Failed to update a configuration field."
,
exception
);
}
});
try
{
// Save configuration & reload.
Grasscutter
.
saveConfig
(
updated
);
Grasscutter
.
reloadConfig
();
}
catch
(
Exception
exception
)
{
Grasscutter
.
getLogger
().
warn
(
"Failed to inject the updated configuration."
,
exception
);
}
}
/*
* Constants
*/
// 'c' is short for 'config' and makes code look 'cleaner'.
public
static
final
Configuration
c
=
config
;
public
static
final
Locale
LANGUAGE
=
config
.
language
.
language
;
public
static
final
Locale
FALLBACK_LANGUAGE
=
config
.
language
.
fallback
;
public
static
final
String
DATA_FOLDER
=
config
.
folderStructure
.
data
;
public
static
final
String
RESOURCES_FOLDER
=
config
.
folderStructure
.
resources
;
public
static
final
String
KEYS_FOLDER
=
config
.
folderStructure
.
keys
;
public
static
final
String
PLUGINS_FOLDER
=
config
.
folderStructure
.
plugins
;
public
static
final
String
SCRIPTS_FOLDER
=
config
.
folderStructure
.
scripts
;
public
static
final
String
PACKETS_FOLDER
=
config
.
folderStructure
.
packets
;
public
static
final
Server
SERVER
=
config
.
server
;
public
static
final
Database
DATABASE
=
config
.
databaseInfo
;
public
static
final
Account
ACCOUNT
=
config
.
account
;
public
static
final
Dispatch
DISPATCH_INFO
=
config
.
server
.
dispatch
;
public
static
final
Game
GAME_INFO
=
config
.
server
.
game
;
public
static
final
Encryption
DISPATCH_ENCRYPTION
=
config
.
server
.
dispatch
.
encryption
;
public
static
final
Policies
DISPATCH_POLICIES
=
config
.
server
.
dispatch
.
policies
;
public
static
final
GameOptions
GAME_OPTIONS
=
config
.
server
.
game
.
gameOptions
;
public
static
final
GameOptions
.
InventoryLimits
INVENTORY_LIMITS
=
config
.
server
.
game
.
gameOptions
.
inventoryLimits
;
/*
* Utilities
*/
public
static
String
DATA
(
String
path
)
{
return
DATA_FOLDER
+
"/"
+
path
;
}
public
static
String
RESOURCE
(
String
path
)
{
return
RESOURCES_FOLDER
+
"/"
+
path
;
}
public
static
String
SCRIPT
(
String
path
)
{
return
SCRIPTS_FOLDER
+
"/"
+
path
;
}
/**
* Fallback method.
* @param left Attempt to use.
* @param right Use if left is undefined.
* @return Left or right.
*/
public
static
<
T
>
T
lr
(
T
left
,
T
right
)
{
return
left
==
null
?
right
:
left
;
}
/**
* {@link Configuration#lr(Object, Object)} for {@link String}s.
* @param left Attempt to use.
* @param right Use if left is empty.
* @return Left or right.
*/
public
static
String
lr
(
String
left
,
String
right
)
{
return
left
.
isEmpty
()
?
right
:
left
;
}
/**
* {@link Configuration#lr(Object, Object)} for {@link Integer}s.
* @param left Attempt to use.
* @param right Use if left is 0.
* @return Left or right.
*/
public
static
int
lr
(
int
left
,
int
right
)
{
return
left
==
0
?
right
:
left
;
}
/*
* Configuration data.
*/
public
Structure
folderStructure
;
public
Database
databaseInfo
;
public
Language
language
;
public
Account
account
;
public
Server
server
;
// DO NOT. TOUCH. THE VERSION NUMBER.
public
int
version
=
version
();
/* Option containers. */
public
static
class
Database
{
...
...
@@ -46,6 +170,11 @@ public final class Configuration {
public
Locale
fallback
=
Locale
.
US
;
}
public
static
class
Account
{
public
boolean
autoCreate
=
false
;
public
String
[]
defaultPermissions
=
{};
}
/* Server options. */
public
static
class
Dispatch
{
...
...
@@ -60,6 +189,8 @@ public final class Configuration {
public
Encryption
encryption
=
new
Encryption
();
public
Policies
policies
=
new
Policies
();
public
Region
[]
regions
=
{};
public
String
defaultName
=
"Grasscutter"
;
}
public
static
class
Game
{
...
...
@@ -100,10 +231,13 @@ public final class Configuration {
public
AvatarLimits
avatarLimits
=
new
AvatarLimits
();
public
int
worldEntityLimit
=
1000
;
// Unenforced. TODO: Implement.
public
boolean
watchGachaConfig
uration
=
false
;
public
boolean
watchGachaConfig
=
false
;
public
boolean
enableShopItems
=
true
;
public
boolean
staminaUsage
=
true
;
public
Rates
rates
=
new
Rates
();
public
Database
databaseInfo
=
new
Database
();
public
static
class
InventoryLimits
{
public
int
weapons
=
2000
;
public
int
relics
=
2000
;
...
...
@@ -127,6 +261,7 @@ public final class Configuration {
public
static
class
JoinOptions
{
public
int
[]
welcomeEmotes
=
{
2007
,
1002
,
4010
};
public
String
welcomeMessage
=
"Welcome to a Grasscutter server."
;
public
Mail
welcomeMail
=
new
Mail
();
public
static
class
Mail
{
public
String
title
=
"Welcome to Grasscutter!"
;
...
...
src/main/java/emu/grasscutter/Grasscutter.java
View file @
11161227
package
emu.grasscutter
;
import
java.io.File
;
import
java.io.FileReader
;
import
java.io.FileWriter
;
import
java.io.IOError
;
import
java.io.*
;
import
java.lang.reflect.Field
;
import
java.util.Arrays
;
import
java.util.Calendar
;
import
emu.grasscutter.command.CommandMap
;
...
...
@@ -32,13 +31,15 @@ import emu.grasscutter.server.game.GameServer;
import
emu.grasscutter.tools.Tools
;
import
emu.grasscutter.utils.Crypto
;
import
javax.annotation.Nullable
;
import
static
emu
.
grasscutter
.
utils
.
Language
.
translate
;
import
static
emu
.
grasscutter
.
Configuration
.*;
public
final
class
Grasscutter
{
private
static
final
Logger
log
=
(
Logger
)
LoggerFactory
.
getLogger
(
Grasscutter
.
class
);
private
static
LineReader
consoleLineReader
=
null
;
private
static
Config
config
;
private
static
Language
language
;
private
static
final
Gson
gson
=
new
GsonBuilder
().
setPrettyPrinting
().
create
();
...
...
@@ -51,13 +52,14 @@ public final class Grasscutter {
private
static
PluginManager
pluginManager
;
public
static
final
Reflections
reflector
=
new
Reflections
(
"emu.grasscutter"
);
public
static
final
Configuration
config
;
static
{
// Declare logback configuration.
System
.
setProperty
(
"logback.configurationFile"
,
"src/main/resources/logback.xml"
);
// Load server configuration.
Grasscutter
.
loadConfig
();
config
=
Grasscutter
.
loadConfig
();
// Load translation files.
Grasscutter
.
loadLanguage
();
...
...
@@ -77,7 +79,7 @@ public final class Grasscutter {
Tools
.
createGmHandbook
();
exitEarly
=
true
;
}
case
"-gachamap"
->
{
Tools
.
createGachaMapping
(
Grasscutter
.
getConfig
().
DATA_FOLDER
+
"/
gacha_mappings.js"
);
exitEarly
=
true
;
Tools
.
createGachaMapping
(
DATA
(
"
gacha_mappings.js"
)
)
;
exitEarly
=
true
;
}
}
}
...
...
@@ -105,15 +107,16 @@ public final class Grasscutter {
pluginManager
=
new
PluginManager
();
// Start servers.
if
(
getConfig
().
RunMode
==
ServerRunMode
.
HYBRID
)
{
var
runMode
=
SERVER
.
runMode
;
if
(
runMode
==
ServerRunMode
.
HYBRID
)
{
dispatchServer
.
start
();
gameServer
.
start
();
}
else
if
(
getConfig
().
R
unMode
==
ServerRunMode
.
DISPATCH_ONLY
)
{
}
else
if
(
r
unMode
==
ServerRunMode
.
DISPATCH_ONLY
)
{
dispatchServer
.
start
();
}
else
if
(
getConfig
().
R
unMode
==
ServerRunMode
.
GAME_ONLY
)
{
}
else
if
(
r
unMode
==
ServerRunMode
.
GAME_ONLY
)
{
gameServer
.
start
();
}
else
{
getLogger
().
error
(
translate
(
"messages.status.run_mode_error"
,
getConfig
().
R
unMode
));
getLogger
().
error
(
translate
(
"messages.status.run_mode_error"
,
r
unMode
));
getLogger
().
error
(
translate
(
"messages.status.run_mode_help"
));
getLogger
().
error
(
translate
(
"messages.status.shutdown"
));
System
.
exit
(
1
);
...
...
@@ -137,32 +140,60 @@ public final class Grasscutter {
pluginManager
.
disablePlugins
();
}
public
static
void
loadConfig
()
{
/**
* Attempts to load the configuration from a file.
* @return The config from the file, or a new instance.
*/
public
static
Configuration
loadConfig
()
{
try
(
FileReader
file
=
new
FileReader
(
configFile
))
{
config
=
gson
.
fromJson
(
file
,
Config
.
class
);
saveConfig
();
return
gson
.
fromJson
(
file
,
Configuration
.
class
);
}
catch
(
Exception
e
)
{
Grasscutter
.
config
=
new
Config
();
saveConfig
();
Grasscutter
.
save
Config
(
null
);
return
new
Configuration
();
}
}
/**
* Attempts to reload the configuration from the file.
* Uses reflection to **replace** the fields in the config.
*/
public
static
void
reloadConfig
()
{
Configuration
fileConfig
=
Grasscutter
.
loadConfig
();
Field
[]
fields
=
Configuration
.
class
.
getDeclaredFields
();
Arrays
.
stream
(
fields
).
forEach
(
field
->
{
try
{
field
.
set
(
config
,
field
.
get
(
fileConfig
));
}
catch
(
Exception
exception
)
{
Grasscutter
.
getLogger
().
error
(
"Failed to update a configuration field."
,
exception
);
}
});
}
public
static
void
loadLanguage
()
{
var
locale
=
config
.
LocaleL
anguage
;
var
locale
=
config
.
language
.
l
anguage
;
language
=
Language
.
getLanguage
(
Utils
.
getLanguageCode
(
locale
));
}
public
static
void
saveConfig
()
{
/**
* Saves the provided server configuration.
* @param config The configuration to save, or null for a new one.
*/
public
static
void
saveConfig
(
@Nullable
Configuration
config
)
{
if
(
config
==
null
)
config
=
new
Configuration
();
try
(
FileWriter
file
=
new
FileWriter
(
configFile
))
{
file
.
write
(
gson
.
toJson
(
config
));
}
catch
(
IOException
ignored
)
{
Grasscutter
.
getLogger
().
error
(
"Unable to write to config file."
);
}
catch
(
Exception
e
)
{
Grasscutter
.
getLogger
().
error
(
"Unable to save config file."
);
Grasscutter
.
getLogger
().
error
(
"Unable to save config file."
,
e
);
}
}
public
static
void
startConsole
()
{
// Console should not start in dispatch only mode.
if
(
getConfig
().
R
unMode
==
ServerRunMode
.
DISPATCH_ONLY
)
{
if
(
SERVER
.
r
unMode
==
ServerRunMode
.
DISPATCH_ONLY
)
{
getLogger
().
info
(
translate
(
"messages.dispatch.no_commands_error"
));
return
;
}
...
...
@@ -198,7 +229,7 @@ public final class Grasscutter {
}
}
public
static
Config
getConfig
()
{
public
static
Config
uration
getConfig
()
{
return
config
;
}
...
...
src/main/java/emu/grasscutter/command/commands/ReloadCommand.java
View file @
11161227
...
...
@@ -16,7 +16,7 @@ public final class ReloadCommand implements CommandHandler {
public
void
execute
(
Player
sender
,
Player
targetPlayer
,
List
<
String
>
args
)
{
CommandHandler
.
sendMessage
(
sender
,
translate
(
sender
,
"commands.reload.reload_start"
));
Grasscutter
.
loadConfig
();
Grasscutter
.
re
loadConfig
();
Grasscutter
.
loadLanguage
();
Grasscutter
.
getGameServer
().
getGachaManager
().
load
();
Grasscutter
.
getGameServer
().
getDropManager
().
load
();
...
...
src/main/java/emu/grasscutter/data/ResourceLoader.java
View file @
11161227
...
...
@@ -25,10 +25,11 @@ import emu.grasscutter.data.custom.AbilityModifier.AbilityModifierActionType;
import
emu.grasscutter.data.custom.AbilityModifierEntry
;
import
emu.grasscutter.data.custom.OpenConfigEntry
;
import
emu.grasscutter.data.custom.ScenePointEntry
;
import
emu.grasscutter.game.world.SpawnDataEntry
;
import
emu.grasscutter.game.world.SpawnDataEntry.SpawnGroupEntry
;
import
emu.grasscutter.game.world.SpawnDataEntry.*
;
import
it.unimi.dsi.fastutil.ints.Int2ObjectMap
;
import
static
emu
.
grasscutter
.
Configuration
.*;
public
class
ResourceLoader
{
public
static
List
<
Class
<?>>
getResourceDefClasses
()
{
...
...
@@ -127,7 +128,7 @@ public class ResourceLoader {
@SuppressWarnings
({
"rawtypes"
,
"unchecked"
})
protected
static
void
loadFromResource
(
Class
<?>
c
,
String
fileName
,
Int2ObjectMap
map
)
throws
Exception
{
FileReader
fileReader
=
new
FileReader
(
Grasscutter
.
getConfig
().
RESOURCE_FOLDER
+
"ExcelBinOutput/"
+
fileName
);
FileReader
fileReader
=
new
FileReader
(
RESOURCE
(
"ExcelBinOutput/"
+
fileName
)
)
;
Gson
gson
=
Grasscutter
.
getGsonFactory
();
List
list
=
gson
.
fromJson
(
fileReader
,
List
.
class
);
...
...
@@ -141,7 +142,7 @@ public class ResourceLoader {
private
static
void
loadScenePoints
()
{
Pattern
pattern
=
Pattern
.
compile
(
"(?<=scene)(.*?)(?=_point.json)"
);
File
folder
=
new
File
(
Grasscutter
.
getConfig
().
RESOURCE_FOLDER
+
"BinOutput/Scene/Point"
);
File
folder
=
new
File
(
RESOURCE
(
"BinOutput/Scene/Point"
)
)
;
if
(!
folder
.
isDirectory
()
||
!
folder
.
exists
()
||
folder
.
listFiles
()
==
null
)
{
Grasscutter
.
getLogger
().
error
(
"Scene point files cannot be found, you cannot use teleport waypoints!"
);
...
...
@@ -150,8 +151,7 @@ public class ResourceLoader {
List
<
ScenePointEntry
>
scenePointList
=
new
ArrayList
<>();
for
(
File
file
:
Objects
.
requireNonNull
(
folder
.
listFiles
()))
{
ScenePointConfig
config
=
null
;
Integer
sceneId
=
null
;
ScenePointConfig
config
;
Integer
sceneId
;
Matcher
matcher
=
pattern
.
matcher
(
file
.
getName
());
if
(
matcher
.
find
())
{
...
...
@@ -190,7 +190,7 @@ public class ResourceLoader {
private
static
void
loadAbilityEmbryos
()
{
// Read from cached file if exists
File
embryoCache
=
new
File
(
Grasscutter
.
getConfig
().
DATA_FOLDER
+
"AbilityEmbryos.json"
);
File
embryoCache
=
new
File
(
DATA
(
"AbilityEmbryos.json"
)
)
;
List
<
AbilityEmbryoEntry
>
embryoList
=
null
;
if
(
embryoCache
.
exists
())
{
...
...
@@ -205,7 +205,7 @@ public class ResourceLoader {
Pattern
pattern
=
Pattern
.
compile
(
"(?<=ConfigAvatar_)(.*?)(?=.json)"
);
embryoList
=
new
LinkedList
<>();
File
folder
=
new
File
(
Utils
.
toFilePath
(
Grasscutter
.
getConfig
().
RESOURCE_FOLDER
+
"BinOutput/Avatar/"
));
File
folder
=
new
File
(
Utils
.
toFilePath
(
RESOURCE
(
"BinOutput/Avatar/"
))
)
;
File
[]
files
=
folder
.
listFiles
();
if
(
files
==
null
)
{
Grasscutter
.
getLogger
().
error
(
"Error loading ability embryos: no files found in "
+
folder
.
getAbsolutePath
());
...
...
@@ -252,7 +252,7 @@ public class ResourceLoader {
private
static
void
loadAbilityModifiers
()
{
// Load from BinOutput
File
folder
=
new
File
(
Utils
.
toFilePath
(
Grasscutter
.
getConfig
().
RESOURCE_FOLDER
+
"BinOutput/Ability/Temp/AvatarAbilities/"
));
File
folder
=
new
File
(
Utils
.
toFilePath
(
RESOURCE
(
"BinOutput/Ability/Temp/AvatarAbilities/"
))
)
;
File
[]
files
=
folder
.
listFiles
();
if
(
files
==
null
)
{
Grasscutter
.
getLogger
().
error
(
"Error loading ability modifiers: no files found in "
+
folder
.
getAbsolutePath
());
...
...
@@ -260,7 +260,7 @@ public class ResourceLoader {
}
for
(
File
file
:
files
)
{
List
<
AbilityConfigData
>
abilityConfigList
=
null
;
List
<
AbilityConfigData
>
abilityConfigList
;
try
(
FileReader
fileReader
=
new
FileReader
(
file
))
{
abilityConfigList
=
Grasscutter
.
getGsonFactory
().
fromJson
(
fileReader
,
TypeToken
.
getParameterized
(
Collection
.
class
,
AbilityConfigData
.
class
).
getType
());
...
...
@@ -315,7 +315,7 @@ public class ResourceLoader {
private
static
void
loadSpawnData
()
{
// Read from cached file if exists
File
spawnDataEntries
=
new
File
(
Grasscutter
.
getConfig
().
DATA_FOLDER
+
"Spawns.json"
);
File
spawnDataEntries
=
new
File
(
DATA
(
"Spawns.json"
)
)
;
List
<
SpawnGroupEntry
>
spawnEntryList
=
null
;
if
(
spawnDataEntries
.
exists
())
{
...
...
@@ -333,16 +333,14 @@ public class ResourceLoader {
}
for
(
SpawnGroupEntry
entry
:
spawnEntryList
)
{
entry
.
getSpawns
().
stream
().
forEach
(
s
->
{
s
.
setGroup
(
entry
);
});
entry
.
getSpawns
().
forEach
(
s
->
s
.
setGroup
(
entry
));
GameDepot
.
getSpawnListById
(
entry
.
getSceneId
()).
insert
(
entry
,
entry
.
getPos
().
getX
(),
entry
.
getPos
().
getZ
());
}
}
private
static
void
loadOpenConfig
()
{
// Read from cached file if exists
File
openConfigCache
=
new
File
(
Grasscutter
.
getConfig
().
DATA_FOLDER
+
"OpenConfig.json"
);
File
openConfigCache
=
new
File
(
DATA
(
"OpenConfig.json"
)
)
;
List
<
OpenConfigEntry
>
list
=
null
;
if
(
openConfigCache
.
exists
())
{
...
...
@@ -357,7 +355,7 @@ public class ResourceLoader {
String
[]
folderNames
=
{
"BinOutput/Talent/EquipTalents/"
,
"BinOutput/Talent/AvatarTalents/"
};
for
(
String
name
:
folderNames
)
{
File
folder
=
new
File
(
Utils
.
toFilePath
(
Grasscutter
.
getConfig
().
RESOURCE_FOLDER
+
name
));
File
folder
=
new
File
(
Utils
.
toFilePath
(
RESOURCE
(
name
))
)
;
File
[]
files
=
folder
.
listFiles
();
if
(
files
==
null
)
{
Grasscutter
.
getLogger
().
error
(
"Error loading open config: no files found in "
+
folder
.
getAbsolutePath
());
return
;
...
...
src/main/java/emu/grasscutter/database/DatabaseManager.java
View file @
11161227
package
emu.grasscutter.database
;
import
com.mongodb.MongoClientURI
;
import
com.mongodb.MongoCommandException
;
import
com.mongodb.client.MongoClient
;
import
com.mongodb.client.MongoClients
;
...
...
@@ -21,11 +20,9 @@ import emu.grasscutter.game.inventory.GameItem;
import
emu.grasscutter.game.mail.Mail
;
import
emu.grasscutter.game.player.Player
;
public
final
class
DatabaseManager
{
private
static
MongoClient
mongoClient
;
private
static
MongoClient
dispatchMongoClient
;
import
static
emu
.
grasscutter
.
Configuration
.*;
public
final
class
DatabaseManager
{
private
static
Datastore
datastore
;
private
static
Datastore
dispatchDatastore
;
...
...
@@ -44,7 +41,7 @@ public final class DatabaseManager {
// Yes. I very dislike this method. However, this will be good for now.
// TODO: Add dispatch routes for player account management
public
static
Datastore
getAccountDatastore
()
{
if
(
Grasscutter
.
getConfig
().
R
unMode
==
ServerRunMode
.
GAME_ONLY
)
{
if
(
SERVER
.
r
unMode
==
ServerRunMode
.
GAME_ONLY
)
{
return
dispatchDatastore
;
}
else
{
return
datastore
;
...
...
@@ -53,13 +50,13 @@ public final class DatabaseManager {
public
static
void
initialize
()
{
// Initialize
MongoClient
mongoClient
=
MongoClients
.
create
(
Grasscutter
.
getConfig
().
Database
Ur
l
);
MongoClient
mongoClient
=
MongoClients
.
create
(
DATABASE
.
connection
Ur
i
);
// Set mapper options.
MapperOptions
mapperOptions
=
MapperOptions
.
builder
()
.
storeEmpties
(
true
).
storeNulls
(
false
).
build
();
// Create data store.
datastore
=
Morphia
.
createDatastore
(
mongoClient
,
Grasscutter
.
getConfig
().
DatabaseC
ollection
,
mapperOptions
);
datastore
=
Morphia
.
createDatastore
(
mongoClient
,
DATABASE
.
c
ollection
,
mapperOptions
);
// Map classes.
datastore
.
getMapper
().
map
(
mappedClasses
);
...
...
@@ -80,9 +77,9 @@ public final class DatabaseManager {
}
}
if
(
Grasscutter
.
getConfig
().
R
unMode
==
ServerRunMode
.
GAME_ONLY
)
{
dispatchMongoClient
=
MongoClients
.
create
(
G
rasscutter
.
getConfig
().
getGameServerOptions
().
DispatchServerDatabase
Ur
l
);
dispatchDatastore
=
Morphia
.
createDatastore
(
dispatchMongoClient
,
G
rasscutter
.
getConfig
().
getGameServerOptions
().
DispatchServerD
atabase
C
ollection
);
if
(
SERVER
.
r
unMode
==
ServerRunMode
.
GAME_ONLY
)
{
MongoClient
dispatchMongoClient
=
MongoClients
.
create
(
G
AME_OPTIONS
.
databaseInfo
.
connection
Ur
i
);
dispatchDatastore
=
Morphia
.
createDatastore
(
dispatchMongoClient
,
G
AME_OPTIONS
.
d
atabase
Info
.
c
ollection
);
// Ensure indexes for dispatch server
try
{
...
...
src/main/java/emu/grasscutter/game/Account.java
View file @
11161227
...
...
@@ -12,7 +12,7 @@ import java.util.Locale;
import
org.bson.Document
;
import
com.mongodb.DBObject
;
import
static
emu
.
grasscutter
.
Configuration
.*
;
@Entity
(
value
=
"accounts"
,
useDiscriminator
=
false
)
public
class
Account
{
...
...
@@ -34,7 +34,7 @@ public class Account {
@Deprecated
public
Account
()
{
this
.
permissions
=
new
ArrayList
<>();
this
.
locale
=
Grasscutter
.
getConfig
().
LocaleLanguage
;
this
.
locale
=
LANGUAGE
;
}
public
String
getId
()
{
...
...
@@ -180,7 +180,7 @@ public class Account {
// Set account default language as server default language
if
(!
document
.
containsKey
(
"locale"
))
{
this
.
locale
=
Grasscutter
.
getConfig
().
LocaleLanguage
;
this
.
locale
=
LANGUAGE
;
}
}
}
src/main/java/emu/grasscutter/game/drop/DropManager.java
View file @
11161227
...
...
@@ -21,6 +21,8 @@ import java.io.FileReader;
import
java.util.Collection
;
import
java.util.List
;
import
static
emu
.
grasscutter
.
Configuration
.*;
public
class
DropManager
{
public
GameServer
getGameServer
()
{
return
gameServer
;
...
...
@@ -41,7 +43,7 @@ public class DropManager {
}
public
synchronized
void
load
()
{
try
(
FileReader
fileReader
=
new
FileReader
(
Grasscutter
.
getConfig
().
DATA_FOLDER
+
"Drop.json"
))
{
try
(
FileReader
fileReader
=
new
FileReader
(
DATA
(
"Drop.json"
))
)
{
getDropData
().
clear
();
List
<
DropInfo
>
banners
=
Grasscutter
.
getGsonFactory
().
fromJson
(
fileReader
,
TypeToken
.
getParameterized
(
Collection
.
class
,
DropInfo
.
class
).
getType
());
if
(
banners
.
size
()
>
0
)
{
...
...
@@ -69,9 +71,7 @@ public class DropManager {
}
else
{
// target is null if items will be added are shared. no one could pick it up because of the combination(give + shared)
// so it will be sent to all players' inventories directly.
dropScene
.
getPlayers
().
forEach
(
x
->
{
x
.
getInventory
().
addItem
(
new
GameItem
(
itemData
,
num
),
ActionReason
.
SubfieldDrop
,
true
);
});
dropScene
.
getPlayers
().
forEach
(
x
->
x
.
getInventory
().
addItem
(
new
GameItem
(
itemData
,
num
),
ActionReason
.
SubfieldDrop
,
true
));
}
}
}
...
...
src/main/java/emu/grasscutter/game/expedition/ExpeditionManager.java
View file @
11161227
...
...
@@ -10,6 +10,8 @@ import java.io.FileReader;
import
java.util.Collection
;
import
java.util.List
;
import
static
emu
.
grasscutter
.
Configuration
.*;
public
class
ExpeditionManager
{
public
GameServer
getGameServer
()
{
return
gameServer
;
...
...
@@ -28,7 +30,7 @@ public class ExpeditionManager {
}
public
synchronized
void
load
()
{
try
(
FileReader
fileReader
=
new
FileReader
(
Grasscutter
.
getConfig
().
DATA_FOLDER
+
"ExpeditionReward.json"
))
{
try
(
FileReader
fileReader
=
new
FileReader
(
DATA
(
"ExpeditionReward.json"
))
)
{
getExpeditionRewardDataList
().
clear
();
List
<
ExpeditionRewardInfo
>
banners
=
Grasscutter
.
getGsonFactory
().
fromJson
(
fileReader
,
TypeToken
.
getParameterized
(
Collection
.
class
,
ExpeditionRewardInfo
.
class
).
getType
());
if
(
banners
.
size
()
>
0
)
{
...
...
src/main/java/emu/grasscutter/game/gacha/GachaBanner.java
View file @
11161227
package
emu.grasscutter.game.gacha
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.net.proto.GachaInfoOuterClass.GachaInfo
;
import
emu.grasscutter.net.proto.GachaUpInfoOuterClass.GachaUpInfo
;
import
static
emu
.
grasscutter
.
Configuration
.*;
public
class
GachaBanner
{
private
int
gachaType
;
private
int
scheduleId
;
...
...
@@ -95,15 +96,11 @@ public class GachaBanner {
public
GachaInfo
toProto
()
{
return
toProto
(
""
);
}
public
GachaInfo
toProto
(
String
sessionKey
)
{
String
record
=
"http"
+
(
Grasscutter
.
getConfig
().
getDispatchOptions
().
FrontHTTPS
?
"s"
:
""
)
+
"://"
+
(
Grasscutter
.
getConfig
().
getDispatchOptions
().
PublicIp
.
isEmpty
()
?
Grasscutter
.
getConfig
().
getDispatchOptions
().
Ip
:
Grasscutter
.
getConfig
().
getDispatchOptions
().
PublicIp
)
+
":"
+
Integer
.
toString
(
Grasscutter
.
getConfig
().
getDispatchOptions
().
PublicPort
==
0
?
Grasscutter
.
getConfig
().
getDispatchOptions
().
Port
:
Grasscutter
.
getConfig
().
getDispatchOptions
().
PublicPort
)
String
record
=
"http"
+
(
DISPATCH_INFO
.
encryption
.
useInRouting
?
"s"
:
""
)
+
"://"
+
lr
(
DISPATCH_INFO
.
accessAddress
,
DISPATCH_INFO
.
bindAddress
)
+
":"
+
lr
(
DISPATCH_INFO
.
accessPort
,
DISPATCH_INFO
.
bindPort
)
+
"/gacha?s="
+
sessionKey
+
"&gachaType="
+
gachaType
;
// Grasscutter.getLogger().info("record = " + record);
GachaInfo
.
Builder
info
=
GachaInfo
.
newBuilder
()
...
...
src/main/java/emu/grasscutter/game/gacha/GachaManager.java
View file @
11161227
...
...
@@ -34,20 +34,22 @@ import it.unimi.dsi.fastutil.ints.IntArrayList;
import
it.unimi.dsi.fastutil.ints.IntList
;
import
org.greenrobot.eventbus.Subscribe
;
import
static
emu
.
grasscutter
.
Configuration
.*;
public
class
GachaManager
{
private
final
GameServer
server
;
private
final
Int2ObjectMap
<
GachaBanner
>
gachaBanners
;
private
GetGachaInfoRsp
cachedProto
;
WatchService
watchService
;
private
int
[]
yellowAvatars
=
new
int
[]
{
1003
,
1016
,
1042
,
1035
,
1041
};
private
int
[]
yellowWeapons
=
new
int
[]
{
11501
,
11502
,
12501
,
12502
,
13502
,
13505
,
14501
,
14502
,
15501
,
15502
};
private
int
[]
purpleAvatars
=
new
int
[]
{
1006
,
1014
,
1015
,
1020
,
1021
,
1023
,
1024
,
1025
,
1027
,
1031
,
1032
,
1034
,
1036
,
1039
,
1043
,
1044
,
1045
,
1048
,
1053
,
1055
,
1056
,
1064
};
private
int
[]
purpleWeapons
=
new
int
[]
{
11401
,
11402
,
11403
,
11405
,
12401
,
12402
,
12403
,
12405
,
13401
,
13407
,
14401
,
14402
,
14403
,
14409
,
15401
,
15402
,
15403
,
15405
};
private
int
[]
blueWeapons
=
new
int
[]
{
11301
,
11302
,
11306
,
12301
,
12302
,
12305
,
13303
,
14301
,
14302
,
14304
,
15301
,
15302
,
15304
};
private
final
int
[]
yellowAvatars
=
new
int
[]
{
1003
,
1016
,
1042
,
1035
,
1041
};
private
final
int
[]
yellowWeapons
=
new
int
[]
{
11501
,
11502
,
12501
,
12502
,
13502
,
13505
,
14501
,
14502
,
15501
,
15502
};
private
final
int
[]
purpleAvatars
=
new
int
[]
{
1006
,
1014
,
1015
,
1020
,
1021
,
1023
,
1024
,
1025
,
1027
,
1031
,
1032
,
1034
,
1036
,
1039
,
1043
,
1044
,
1045
,
1048
,
1053
,
1055
,
1056
,
1064
};
private
final
int
[]
purpleWeapons
=
new
int
[]
{
11401
,
11402
,
11403
,
11405
,
12401
,
12402
,
12403
,
12405
,
13401
,
13407
,
14401
,
14402
,
14403
,
14409
,
15401
,
15402
,
15403
,
15405
};
private
final
int
[]
blueWeapons
=
new
int
[]
{
11301
,
11302
,
11306
,
12301
,
12302
,
12305
,
13303
,
14301
,
14302
,
14304
,
15301
,
15302
,
15304
};
private
static
int
starglitterId
=
221
;
private
static
int
stardustId
=
222
;
private
static
final
int
starglitterId
=
221
;
private
static
final
int
stardustId
=
222
;
public
GachaManager
(
GameServer
server
)
{
this
.
server
=
server
;
...
...
@@ -73,7 +75,7 @@ public class GachaManager {
}
public
synchronized
void
load
()
{
try
(
FileReader
fileReader
=
new
FileReader
(
Grasscutter
.
getConfig
().
DATA_FOLDER
+
"Banners.json"
))
{
try
(
FileReader
fileReader
=
new
FileReader
(
DATA
(
"Banners.json"
))
)
{
getGachaBanners
().
clear
();
List
<
GachaBanner
>
banners
=
Grasscutter
.
getGsonFactory
().
fromJson
(
fileReader
,
TypeToken
.
getParameterized
(
Collection
.
class
,
GachaBanner
.
class
).
getType
());
if
(
banners
.
size
()
>
0
)
{
...
...
@@ -242,15 +244,9 @@ public class GachaManager {
}
else
{
// Is weapon
switch
(
itemData
.
getRankLevel
())
{
case
5
:
addStarglitter
=
10
;
break
;
case
4
:
addStarglitter
=
2
;
break
;
case
3
:
addStardust
=
15
;
break
;
case
5
->
addStarglitter
=
10
;
case
4
->
addStarglitter
=
2
;
case
3
->
addStardust
=
15
;
}
}
...
...
@@ -290,7 +286,7 @@ public class GachaManager {
if
(
this
.
watchService
==
null
)
{
try
{
this
.
watchService
=
FileSystems
.
getDefault
().
newWatchService
();
Path
path
=
new
File
(
Grasscutter
.
getConfig
().
DATA_FOLDER
).
toPath
();
Path
path
=
new
File
(
DATA_FOLDER
).
toPath
();
path
.
register
(
watchService
,
new
WatchEvent
.
Kind
[]{
StandardWatchEventKinds
.
ENTRY_MODIFY
},
SensitivityWatchEventModifier
.
HIGH
);
}
catch
(
Exception
e
)
{
Grasscutter
.
getLogger
().
error
(
"Unable to load the Gacha Manager Watch Service. If ServerOptions.watchGacha is true it will not auto-reload"
);
...
...
@@ -303,7 +299,7 @@ public class GachaManager {
@Subscribe
public
synchronized
void
watchBannerJson
(
GameServerTickEvent
tickEvent
)
{
if
(
G
rasscutter
.
getConfig
().
getGameServerOptions
().
W
atchGacha
)
{
if
(
G
AME_OPTIONS
.
w
atchGacha
Config
)
{
try
{
WatchKey
watchKey
=
watchService
.
take
();
...
...
src/main/java/emu/grasscutter/game/inventory/Inventory.java
View file @
11161227
...
...
@@ -6,7 +6,6 @@ import java.util.LinkedList;
import
java.util.List
;
import
emu.grasscutter.GameConstants
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.def.AvatarCostumeData
;
import
emu.grasscutter.data.def.AvatarData
;
...
...
@@ -15,7 +14,6 @@ import emu.grasscutter.data.def.ItemData;
import
emu.grasscutter.database.DatabaseHelper
;
import
emu.grasscutter.game.avatar.AvatarStorage
;
import
emu.grasscutter.game.avatar.Avatar
;
import
emu.grasscutter.game.entity.EntityAvatar
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.props.ActionReason
;
import
emu.grasscutter.net.proto.ItemParamOuterClass.ItemParam
;
...
...
@@ -28,6 +26,8 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import
it.unimi.dsi.fastutil.longs.Long2ObjectMap
;
import
it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap
;
import
static
emu
.
grasscutter
.
Configuration
.*;
public
class
Inventory
implements
Iterable
<
GameItem
>
{
private
final
Player
player
;
...
...
@@ -39,10 +39,10 @@ public class Inventory implements Iterable<GameItem> {
this
.
store
=
new
Long2ObjectOpenHashMap
<>();
this
.
inventoryTypes
=
new
Int2ObjectOpenHashMap
<>();
this
.
createInventoryTab
(
ItemType
.
ITEM_WEAPON
,
new
EquipInventoryTab
(
Grasscutter
.
getConfig
().
getGameServerOptions
().
InventoryLimitWeapon
));
this
.
createInventoryTab
(
ItemType
.
ITEM_RELIQUARY
,
new
EquipInventoryTab
(
Grasscutter
.
getConfig
().
getGameServerOptions
().
InventoryLimitR
elic
));
this
.
createInventoryTab
(
ItemType
.
ITEM_MATERIAL
,
new
MaterialInventoryTab
(
Grasscutter
.
getConfig
().
getGameServerOptions
().
InventoryLimitM
aterial
));
this
.
createInventoryTab
(
ItemType
.
ITEM_FURNITURE
,
new
MaterialInventoryTab
(
Grasscutter
.
getConfig
().
getGameServerOptions
().
InventoryLimitF
urniture
));
this
.
createInventoryTab
(
ItemType
.
ITEM_WEAPON
,
new
EquipInventoryTab
(
INVENTORY_LIMITS
.
weapons
));
this
.
createInventoryTab
(
ItemType
.
ITEM_RELIQUARY
,
new
EquipInventoryTab
(
INVENTORY_LIMITS
.
r
elic
s
));
this
.
createInventoryTab
(
ItemType
.
ITEM_MATERIAL
,
new
MaterialInventoryTab
(
INVENTORY_LIMITS
.
m
aterial
s
));
this
.
createInventoryTab
(
ItemType
.
ITEM_FURNITURE
,
new
MaterialInventoryTab
(
INVENTORY_LIMITS
.
f
urniture
));
}
public
Player
getPlayer
()
{
...
...
@@ -242,24 +242,18 @@ public class Inventory implements Iterable<GameItem> {
private
void
addVirtualItem
(
int
itemId
,
int
count
)
{
switch
(
itemId
)
{
case
101
:
// Character exp
case
101
->
// Character exp
getPlayer
().
getServer
().
getInventoryManager
().
upgradeAvatar
(
player
,
getPlayer
().
getTeamManager
().
getCurrentAvatarEntity
().
getAvatar
(),
count
);
break
;
case
102
:
// Adventure exp
case
102
->
// Adventure exp
getPlayer
().
addExpDirectly
(
count
);
break
;
case
105
:
// Companionship exp
case
105
->
// Companionship exp
getPlayer
().
getServer
().
getInventoryManager
().
upgradeAvatarFetterLevel
(
player
,
getPlayer
().
getTeamManager
().
getCurrentAvatarEntity
().
getAvatar
(),
count
);
break
;
case
201
:
// Primogem
case
201
->
// Primogem
getPlayer
().
setPrimogems
(
player
.
getPrimogems
()
+
count
);
break
;
case
202
:
// Mora
case
202
->
// Mora
getPlayer
().
setMora
(
player
.
getMora
()
+
count
);
break
;
case
203
:
// Genesis Crystals
case
203
->
// Genesis Crystals
getPlayer
().
setCrystals
(
player
.
getCrystals
()
+
count
);
break
;
}
}
...
...
src/main/java/emu/grasscutter/game/managers/StaminaManager/StaminaManager.java
View file @
11161227
...
...
@@ -20,6 +20,8 @@ import org.jetbrains.annotations.NotNull;
import
java.lang.Math
;
import
java.util.*
;
import
static
emu
.
grasscutter
.
Configuration
.*;
public
class
StaminaManager
{
// TODO: Skiff state detection?
...
...
@@ -224,9 +226,10 @@ public class StaminaManager {
// Returns new stamina and sends PlayerPropNotify
public
int
setStamina
(
GameSession
session
,
String
reason
,
int
newStamina
)
{
if
(!
G
rasscutter
.
getConfig
().
OpenS
tamina
)
{
if
(!
G
AME_OPTIONS
.
s
tamina
Usage
)
{
newStamina
=
player
.
getProperty
(
PlayerProperty
.
PROP_MAX_STAMINA
);
}
// set stamina
player
.
setProperty
(
PlayerProperty
.
PROP_CUR_PERSIST_STAMINA
,
newStamina
);
session
.
send
(
new
PacketPlayerPropNotify
(
player
,
PlayerProperty
.
PROP_CUR_PERSIST_STAMINA
));
...
...
src/main/java/emu/grasscutter/game/player/Player.java
View file @
11161227
...
...
@@ -60,6 +60,8 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import
java.util.*
;
import
java.util.concurrent.LinkedBlockingQueue
;
import
static
emu
.
grasscutter
.
Configuration
.*;
@Entity
(
value
=
"players"
,
useDiscriminator
=
false
)
public
class
Player
{
...
...
@@ -353,7 +355,7 @@ public class Player {
}
private
float
getExpModifier
()
{
return
G
rasscutter
.
getConfig
().
getGameServerOptions
().
getGameRates
().
ADVENTURE_EXP_RATE
;
return
G
AME_OPTIONS
.
rates
.
adventureExp
;
}
// Affected by exp rate
...
...
@@ -1218,7 +1220,7 @@ public class Player {
}
else
if
(
prop
==
PlayerProperty
.
PROP_LAST_CHANGE_AVATAR_TIME
)
{
// 10001
// TODO: implement sanity check
}
else
if
(
prop
==
PlayerProperty
.
PROP_MAX_SPRING_VOLUME
)
{
// 10002
if
(!(
value
>=
0
&&
value
<=
get
SotSManager
()
.
GlobalMaximumSpringVolume
))
{
return
false
;
}
if
(!(
value
>=
0
&&
value
<=
SotSManager
.
GlobalMaximumSpringVolume
))
{
return
false
;
}
}
else
if
(
prop
==
PlayerProperty
.
PROP_CUR_SPRING_VOLUME
)
{
// 10003
int
playerMaximumSpringVolume
=
getProperty
(
PlayerProperty
.
PROP_MAX_SPRING_VOLUME
);
if
(!(
value
>=
0
&&
value
<=
playerMaximumSpringVolume
))
{
return
false
;
}
...
...
@@ -1235,7 +1237,7 @@ public class Player {
}
else
if
(
prop
==
PlayerProperty
.
PROP_IS_TRANSFERABLE
)
{
// 10009
if
(!(
0
<=
value
&&
value
<=
1
))
{
return
false
;
}
}
else
if
(
prop
==
PlayerProperty
.
PROP_MAX_STAMINA
)
{
// 10010
if
(!(
value
>=
0
&&
value
<=
get
StaminaManager
()
.
GlobalMaximumStamina
))
{
return
false
;
}
if
(!(
value
>=
0
&&
value
<=
StaminaManager
.
GlobalMaximumStamina
))
{
return
false
;
}
}
else
if
(
prop
==
PlayerProperty
.
PROP_CUR_PERSIST_STAMINA
)
{
// 10011
int
playerMaximumStamina
=
getProperty
(
PlayerProperty
.
PROP_MAX_STAMINA
);
if
(!(
value
>=
0
&&
value
<=
playerMaximumStamina
))
{
return
false
;
}
...
...
src/main/java/emu/grasscutter/game/player/TeamInfo.java
View file @
11161227
...
...
@@ -4,10 +4,10 @@ import java.util.ArrayList;
import
java.util.List
;
import
dev.morphia.annotations.Entity
;
import
emu.grasscutter.GameConstants
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.game.avatar.Avatar
;
import
static
emu
.
grasscutter
.
Configuration
.*;
@Entity
public
class
TeamInfo
{
private
String
name
;
...
...
@@ -15,7 +15,7 @@ public class TeamInfo {
public
TeamInfo
()
{
this
.
name
=
""
;
this
.
avatars
=
new
ArrayList
<>(
G
rasscutter
.
getConfig
().
getGameServerOptions
().
MaxAvatarsIn
Team
);
this
.
avatars
=
new
ArrayList
<>(
G
AME_OPTIONS
.
avatarLimits
.
singlePlayer
Team
);
}
public
TeamInfo
(
List
<
Integer
>
avatars
)
{
...
...
@@ -44,7 +44,7 @@ public class TeamInfo {
}
public
boolean
addAvatar
(
Avatar
avatar
)
{
if
(
size
()
>=
G
rasscutter
.
getConfig
().
getGameServerOptions
().
MaxAvatarsIn
Team
||
contains
(
avatar
))
{
if
(
size
()
>=
G
AME_OPTIONS
.
avatarLimits
.
singlePlayer
Team
||
contains
(
avatar
))
{
return
false
;
}
...
...
@@ -64,7 +64,7 @@ public class TeamInfo {
}
public
void
copyFrom
(
TeamInfo
team
)
{
copyFrom
(
team
,
G
rasscutter
.
getConfig
().
getGameServerOptions
().
MaxAvatarsIn
Team
);
copyFrom
(
team
,
G
AME_OPTIONS
.
avatarLimits
.
singlePlayer
Team
);
}
public
void
copyFrom
(
TeamInfo
team
,
int
maxTeamSize
)
{
...
...
src/main/java/emu/grasscutter/game/player/TeamManager.java
View file @
11161227
...
...
@@ -5,7 +5,6 @@ import java.util.*;
import
dev.morphia.annotations.Entity
;
import
dev.morphia.annotations.Transient
;
import
emu.grasscutter.GameConstants
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.data.def.AvatarSkillDepotData
;
import
emu.grasscutter.game.avatar.Avatar
;
import
emu.grasscutter.game.entity.EntityAvatar
;
...
...
@@ -40,6 +39,8 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import
it.unimi.dsi.fastutil.ints.IntOpenHashSet
;
import
it.unimi.dsi.fastutil.ints.IntSet
;
import
static
emu
.
grasscutter
.
Configuration
.*;
@Entity
public
class
TeamManager
{
@Transient
private
Player
player
;
...
...
@@ -174,13 +175,14 @@ public class TeamManager {
public
int
getMaxTeamSize
()
{
if
(
getPlayer
().
isInMultiplayer
())
{
int
max
=
G
rasscutter
.
getConfig
().
getGameServerOptions
().
MaxAvatarsInTeamM
ultiplayer
;
int
max
=
G
AME_OPTIONS
.
avatarLimits
.
m
ultiplayer
Team
;
if
(
getPlayer
().
getWorld
().
getHost
()
==
this
.
getPlayer
())
{
return
Math
.
max
(
1
,
(
int
)
Math
.
ceil
(
max
/
(
double
)
getWorld
().
getPlayerCount
()));
}
return
Math
.
max
(
1
,
(
int
)
Math
.
floor
(
max
/
(
double
)
getWorld
().
getPlayerCount
()));
}
return
Grasscutter
.
getConfig
().
getGameServerOptions
().
MaxAvatarsInTeam
;
return
GAME_OPTIONS
.
avatarLimits
.
singlePlayerTeam
;
}
// Methods
...
...
@@ -236,7 +238,7 @@ public class TeamManager {
// Add back entities into team
for
(
int
i
=
0
;
i
<
this
.
getCurrentTeamInfo
().
getAvatars
().
size
();
i
++)
{
int
avatarId
=
this
.
getCurrentTeamInfo
().
getAvatars
().
get
(
i
);
EntityAvatar
entity
=
null
;
EntityAvatar
entity
;
if
(
existingAvatars
.
containsKey
(
avatarId
))
{
entity
=
existingAvatars
.
get
(
avatarId
);
...
...
@@ -303,8 +305,8 @@ public class TeamManager {
// Set team data
LinkedHashSet
<
Avatar
>
newTeam
=
new
LinkedHashSet
<>();
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++
)
{
Avatar
avatar
=
getPlayer
().
getAvatars
().
getAvatarByGuid
(
list
.
get
(
i
)
);
for
(
Long
aLong
:
list
)
{
Avatar
avatar
=
getPlayer
().
getAvatars
().
getAvatarByGuid
(
aLong
);
if
(
avatar
==
null
||
newTeam
.
contains
(
avatar
))
{
// Should never happen
return
;
...
...
@@ -339,8 +341,8 @@ public class TeamManager {
// Set team data
LinkedHashSet
<
Avatar
>
newTeam
=
new
LinkedHashSet
<>();
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++
)
{
Avatar
avatar
=
getPlayer
().
getAvatars
().
getAvatarByGuid
(
list
.
get
(
i
)
);
for
(
Long
aLong
:
list
)
{
Avatar
avatar
=
getPlayer
().
getAvatars
().
getAvatarByGuid
(
aLong
);
if
(
avatar
==
null
||
newTeam
.
contains
(
avatar
))
{
// Should never happen
return
;
...
...
@@ -359,7 +361,7 @@ public class TeamManager {
}
public
void
setupTemporaryTeam
(
List
<
List
<
Long
>>
guidList
)
{
var
t
eam
=
guidList
.
stream
().
map
(
list
->
{
this
.
temporaryT
eam
=
guidList
.
stream
().
map
(
list
->
{
// Sanity checks
if
(
list
.
size
()
==
0
||
list
.
size
()
>
getMaxTeamSize
())
{
return
null
;
...
...
@@ -367,8 +369,8 @@ public class TeamManager {
// Set team data
LinkedHashSet
<
Avatar
>
newTeam
=
new
LinkedHashSet
<>();
for
(
int
i
=
0
;
i
<
list
.
size
();
i
++
)
{
Avatar
avatar
=
getPlayer
().
getAvatars
().
getAvatarByGuid
(
list
.
get
(
i
)
);
for
(
Long
aLong
:
list
)
{
Avatar
avatar
=
getPlayer
().
getAvatars
().
getAvatarByGuid
(
aLong
);
if
(
avatar
==
null
||
newTeam
.
contains
(
avatar
))
{
// Should never happen
return
null
;
...
...
@@ -384,7 +386,6 @@ public class TeamManager {
.
filter
(
Objects:
:
nonNull
)
.
map
(
TeamInfo:
:
new
)
.
toList
();
this
.
temporaryTeam
=
team
;
}
public
void
useTemporaryTeam
(
int
index
)
{
...
...
src/main/java/emu/grasscutter/game/shop/ShopManager.java
View file @
11161227
...
...
@@ -16,6 +16,8 @@ import java.util.Collection;
import
java.util.Iterator
;
import
java.util.List
;
import
static
emu
.
grasscutter
.
Configuration
.*;
public
class
ShopManager
{
private
final
GameServer
server
;
...
...
@@ -56,7 +58,7 @@ public class ShopManager {
}
private
void
loadShop
()
{
try
(
FileReader
fileReader
=
new
FileReader
(
Grasscutter
.
getConfig
().
DATA_FOLDER
+
"Shop.json"
))
{
try
(
FileReader
fileReader
=
new
FileReader
(
DATA
(
"Shop.json"
))
)
{
getShopData
().
clear
();
List
<
ShopTable
>
banners
=
Grasscutter
.
getGsonFactory
().
fromJson
(
fileReader
,
TypeToken
.
getParameterized
(
Collection
.
class
,
ShopTable
.
class
).
getType
());
if
(
banners
.
size
()
>
0
)
{
...
...
@@ -84,7 +86,7 @@ public class ShopManager {
Grasscutter
.
getLogger
().
error
(
"Unable to load shop data. Shop data size is 0."
);
}
if
(
G
rasscutter
.
getConfig
().
getGameServerOptions
().
EnableOfficialShop
)
{
if
(
G
AME_OPTIONS
.
enableShopItems
)
{
GameData
.
getShopGoodsDataEntries
().
forEach
((
k
,
v
)
->
{
if
(!
getShopData
().
containsKey
(
k
.
intValue
()))
getShopData
().
put
(
k
.
intValue
(),
new
ArrayList
<>());
...
...
@@ -100,7 +102,7 @@ public class ShopManager {
}
private
void
loadShopChest
()
{
try
(
FileReader
fileReader
=
new
FileReader
(
Grasscutter
.
getConfig
().
DATA_FOLDER
+
"ShopChest.json"
))
{
try
(
FileReader
fileReader
=
new
FileReader
(
DATA
(
"ShopChest.json"
))
)
{
getShopChestData
().
clear
();
List
<
ShopChestTable
>
shopChestTableList
=
Grasscutter
.
getGsonFactory
().
fromJson
(
fileReader
,
TypeToken
.
getParameterized
(
Collection
.
class
,
ShopChestTable
.
class
).
getType
());
if
(
shopChestTableList
.
size
()
>
0
)
{
...
...
@@ -115,7 +117,7 @@ public class ShopManager {
}
private
void
loadShopChestBatchUse
()
{
try
(
FileReader
fileReader
=
new
FileReader
(
Grasscutter
.
getConfig
().
DATA_FOLDER
+
"ShopChestBatchUse.json"
))
{
try
(
FileReader
fileReader
=
new
FileReader
(
DATA
(
"ShopChestBatchUse.json"
))
)
{
getShopChestBatchUseData
().
clear
();
List
<
ShopChestBatchUseTable
>
shopChestBatchUseTableList
=
Grasscutter
.
getGsonFactory
().
fromJson
(
fileReader
,
TypeToken
.
getParameterized
(
Collection
.
class
,
ShopChestBatchUseTable
.
class
).
getType
());
if
(
shopChestBatchUseTableList
.
size
()
>
0
)
{
...
...
src/main/java/emu/grasscutter/game/tower/TowerScheduleManager.java
View file @
11161227
...
...
@@ -8,6 +8,8 @@ import emu.grasscutter.server.game.GameServer;
import
java.io.FileReader
;
import
java.util.List
;
import
static
emu
.
grasscutter
.
Configuration
.*;
public
class
TowerScheduleManager
{
private
final
GameServer
gameServer
;
...
...
@@ -23,9 +25,8 @@ public class TowerScheduleManager {
private
TowerScheduleConfig
towerScheduleConfig
;
public
synchronized
void
load
(){
try
(
FileReader
fileReader
=
new
FileReader
(
Grasscutter
.
getConfig
().
DATA_FOLDER
+
"TowerSchedule.json"
))
{
try
(
FileReader
fileReader
=
new
FileReader
(
DATA
(
"TowerSchedule.json"
))
)
{
towerScheduleConfig
=
Grasscutter
.
getGsonFactory
().
fromJson
(
fileReader
,
TowerScheduleConfig
.
class
);
}
catch
(
Exception
e
)
{
Grasscutter
.
getLogger
().
error
(
"Unable to load tower schedule config."
,
e
);
}
...
...
@@ -40,6 +41,7 @@ public class TowerScheduleManager {
if
(
data
==
null
){
Grasscutter
.
getLogger
().
error
(
"Could not get current tower schedule data by config:{}"
,
towerScheduleConfig
);
}
return
data
;
}
...
...
@@ -51,28 +53,31 @@ public class TowerScheduleManager {
var
entranceFloors
=
getCurrentTowerScheduleData
().
getEntranceFloorId
();
var
scheduleFloors
=
getScheduleFloors
();
var
nextId
=
0
;
// find in entrance floors first
for
(
int
i
=
0
;
i
<
entranceFloors
.
size
()-
1
;
i
++){
if
(
floorId
==
entranceFloors
.
get
(
i
)){
nextId
=
entranceFloors
.
get
(
i
+
1
);
}
}
if
(
floorId
==
entranceFloors
.
get
(
entranceFloors
.
size
()-
1
)){
nextId
=
scheduleFloors
.
get
(
0
);
}
if
(
nextId
!=
0
){
return
nextId
;
}
// find in schedule floors
for
(
int
i
=
0
;
i
<
scheduleFloors
.
size
()
-
1
;
i
++){
for
(
int
i
=
0
;
i
<
scheduleFloors
.
size
()
-
1
;
i
++){
if
(
floorId
==
scheduleFloors
.
get
(
i
)){
nextId
=
scheduleFloors
.
get
(
i
+
1
);
nextId
=
scheduleFloors
.
get
(
i
+
1
);
}
}
return
nextId
;
}
return
nextId
;
}
public
Integer
getLastEntranceFloor
()
{
return
getCurrentTowerScheduleData
().
getEntranceFloorId
().
get
(
getCurrentTowerScheduleData
().
getEntranceFloorId
().
size
()
-
1
);
return
getCurrentTowerScheduleData
().
getEntranceFloorId
().
get
(
getCurrentTowerScheduleData
().
getEntranceFloorId
().
size
()
-
1
);
}
}
src/main/java/emu/grasscutter/game/world/World.java
View file @
11161227
package
emu.grasscutter.game.world
;
import
java.util.ArrayList
;
import
java.util.Collection
;
import
java.util.Collections
;
import
java.util.Iterator
;
import
java.util.LinkedList
;
import
java.util.List
;
import
java.util.stream.Collectors
;
import
emu.grasscutter.game.entity.GameEntity
;
import
emu.grasscutter.game.player.Player
;
import
emu.grasscutter.game.player.Player.SceneLoadState
;
import
emu.grasscutter.game.props.ClimateType
;
import
emu.grasscutter.game.props.EnterReason
;
import
emu.grasscutter.game.props.EntityIdType
;
import
emu.grasscutter.game.props.FightProperty
;
import
emu.grasscutter.game.props.LifeState
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.def.DungeonData
;
import
emu.grasscutter.data.def.SceneData
;
import
emu.grasscutter.game.entity.EntityAvatar
;
import
emu.grasscutter.game.entity.EntityClientGadget
;
import
emu.grasscutter.game.entity.EntityBaseGadget
;
import
emu.grasscutter.net.packet.BasePacket
;
import
emu.grasscutter.net.proto.AttackResultOuterClass.AttackResult
;
import
emu.grasscutter.net.proto.EnterTypeOuterClass.EnterType
;
import
emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType
;
import
emu.grasscutter.scripts.data.SceneConfig
;
import
emu.grasscutter.server.game.GameServer
;
import
emu.grasscutter.server.packet.send.PacketDelTeamEntityNotify
;
import
emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify
;
import
emu.grasscutter.server.packet.send.PacketPlayerEnterSceneNotify
;
import
emu.grasscutter.server.packet.send.PacketSceneEntityAppearNotify
;
import
emu.grasscutter.server.packet.send.PacketSceneEntityDisappearNotify
;
import
emu.grasscutter.server.packet.send.PacketScenePlayerInfoNotify
;
import
emu.grasscutter.server.packet.send.PacketSyncScenePlayTeamEntityNotify
;
import
emu.grasscutter.server.packet.send.PacketSyncTeamEntityNotify
;
...
...
src/main/java/emu/grasscutter/plugin/Plugin.java
View file @
11161227
...
...
@@ -8,6 +8,8 @@ import java.io.File;
import
java.io.InputStream
;
import
java.net.URLClassLoader
;
import
static
emu
.
grasscutter
.
Configuration
.*;
/**
* The base class for all plugins to extend.
*/
...
...
@@ -32,7 +34,7 @@ public abstract class Plugin {
this
.
identifier
=
identifier
;
this
.
classLoader
=
classLoader
;
this
.
dataFolder
=
new
File
(
Grasscutter
.
getConfig
().
PLUGINS_FOLDER
,
identifier
.
name
);
this
.
dataFolder
=
new
File
(
PLUGINS_FOLDER
,
identifier
.
name
);
if
(!
this
.
dataFolder
.
exists
()
&&
!
this
.
dataFolder
.
mkdirs
())
{
Grasscutter
.
getLogger
().
warn
(
"Failed to create plugin data folder for "
+
this
.
identifier
.
name
);
...
...
src/main/java/emu/grasscutter/plugin/PluginManager.java
View file @
11161227
...
...
@@ -16,6 +16,8 @@ import java.util.*;
import
java.util.jar.JarEntry
;
import
java.util.jar.JarFile
;
import
static
emu
.
grasscutter
.
Configuration
.*;
/**
* Manages the server's plugins and the event system.
*/
...
...
@@ -31,8 +33,7 @@ public final class PluginManager {
* Loads plugins from the config-specified directory.
*/
private
void
loadPlugins
()
{
String
directory
=
Grasscutter
.
getConfig
().
PLUGINS_FOLDER
;
File
pluginsDir
=
new
File
(
Utils
.
toFilePath
(
directory
));
File
pluginsDir
=
new
File
(
Utils
.
toFilePath
(
PLUGINS_FOLDER
));
if
(!
pluginsDir
.
exists
()
&&
!
pluginsDir
.
mkdirs
())
{
Grasscutter
.
getLogger
().
error
(
"Failed to create plugins directory: "
+
pluginsDir
.
getAbsolutePath
());
return
;
...
...
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