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
b9f7c657
Commit
b9f7c657
authored
Apr 27, 2022
by
Benjamin Elsdon
Browse files
Merge remote-tracking branch 'upstream/development' into dev-mail
parents
eb495807
782618cd
Changes
86
Hide whitespace changes
Inline
Side-by-side
.gitignore
View file @
b9f7c657
...
...
@@ -30,6 +30,9 @@ hs_err_pid*
build/
out/
# Ignore Gradle properties
gradle.properties
# Eclipse
.project
.classpath
...
...
@@ -53,9 +56,10 @@ resources/*
logs/*
data/AbilityEmbryos.json
data/OpenConfig.json
proto/*
GM Handbook.txt
config.json
mitmdump.exe
grasscutter.jar
mongod.exe
\ No newline at end of file
*.jar
mongod.exe
/src/generated/
/*.sh
\ No newline at end of file
.gitmodules
deleted
100644 → 0
View file @
eb495807
[submodule "Grasscutter-Protos"]
path = Grasscutter-Protos
url = https://github.com/Melledy/Grasscutter-Protos
Grasscutter-Protos
@
ba0eab7d
Compare
ba0eab7d
...
ba0eab7d
Subproject commit ba0eab7d629b5adeb145bc430e14ffcb4bdf3d6a
README.md
View file @
b9f7c657
...
...
@@ -75,7 +75,7 @@ Grasscutter uses Gradle to handle dependencies & building.
**Requirements:**
-
Java SE Development Kits - 1
6
-
Java SE Development Kits - 1
7
-
Git
##### Windows
...
...
README_zh-CN.md
View file @
b9f7c657
...
...
@@ -75,7 +75,7 @@ Grasscutter 使用 Gradle 来处理依赖及构建.
**依赖:**
-
Java SE Development Kits - 1
6
-
Java SE Development Kits - 1
7
-
Git
##### Windows
...
...
build.gradle
View file @
b9f7c657
...
...
@@ -6,24 +6,52 @@
* User Manual available at https://docs.gradle.org/5.6.3/userguide/tutorial_java_projects.html
*/
buildscript
{
repositories
{
maven
{
url
"https://plugins.gradle.org/m2/"
}
}
dependencies
{
classpath
'com.google.protobuf:protobuf-gradle-plugin:0.8.18'
}
}
plugins
{
// Apply the java plugin to add support for Java
id
'java'
// Apply the protobuf auto generator
id
'com.google.protobuf'
version
"0.8.18"
id
'idea'
// Apply the application plugin to add support for building a CLI application
id
'application'
id
'maven-publish'
id
'signing'
}
sourceCompatibility
=
JavaVersion
.
VERSION_17
targetCompatibility
=
JavaVersion
.
VERSION_17
group
=
'tech.xigam'
version
=
'1.0.0-dev'
sourceCompatibility
=
17
targetCompatibility
=
17
java
{
withJavadocJar
()
withSourcesJar
()
}
repositories
{
mavenCentral
()
}
dependencies
{
implementation
fileTree
(
dir:
'lib'
,
include:
[
'*.jar'
])
implementation
group:
'org.slf4j'
,
name:
'slf4j-api'
,
version:
'1.7.32'
implementation
group:
'ch.qos.logback'
,
name:
'logback-core'
,
version:
'1.2.9'
implementation
group:
'ch.qos.logback'
,
name:
'logback-classic'
,
version:
'1.2.9'
...
...
@@ -38,6 +66,9 @@ dependencies {
implementation
group:
'org.greenrobot'
,
name:
'eventbus-java'
,
version:
'3.3.1'
implementation
group:
'org.danilopianini'
,
name:
'java-quadtree'
,
version:
'0.1.9'
protobuf
files
(
'proto/'
)
}
application
{
...
...
@@ -65,3 +96,102 @@ jar {
destinationDir
=
file
(
"."
)
}
publishing
{
publications
{
mavenJava
(
MavenPublication
)
{
artifactId
=
'grasscutter'
from
components
.
java
versionMapping
{
usage
(
'java-api'
)
{
fromResolutionOf
(
'runtimeClasspath'
)
}
usage
(
'java-runtime'
)
{
fromResolutionResult
()
}
}
pom
{
name
=
'Grasscutter'
description
=
'A server software reimplementation for an anime game.'
url
=
'https://github.com/Grasscutters/Grasscutter'
licenses
{
license
{
name
=
'The Apache License, Version 2.0'
url
=
'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
developers
{
developer
{
id
=
'melledy'
name
=
'Melledy'
email
=
'melledy@xigam.tech'
// not a real email kek
}
developer
{
id
=
'magix'
name
=
'Magix'
email
=
'magix@xigam.tech'
}
}
scm
{
connection
=
'scm:git:git@github.com:Grasscutters/Grasscutter.git'
developerConnection
=
'scm:git:ssh://github.com:Grasscutters/Grasscutter.git'
url
=
'https://github.com/Grasscutters/Grasscutter'
}
}
}
}
repositories
{
maven
{
// change URLs to point to your repos, e.g. http://my.org/repo
def
releasesRepoUrl
=
'https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/'
def
snapshotsRepoUrl
=
'https://s01.oss.sonatype.org/content/repositories/snapshots/'
url
=
version
.
endsWith
(
'SNAPSHOT'
)
?
snapshotsRepoUrl
:
releasesRepoUrl
name
=
'sonatype'
credentials
(
PasswordCredentials
)
}
}
}
clean
{
delete
protobuf
.
generatedFilesBaseDir
}
protobuf
{
protoc
{
// The artifact spec for the Protobuf Compiler
artifact
=
'com.google.protobuf:protoc:3.18.1'
}
// generatedFilesBaseDir = "$projectDir/src/main/java/emu/grasscutter/net/proto/"
generatedFilesBaseDir
=
"$projectDir/src/generated/"
}
sourceSets
{
main
{
proto
{
// In addition to the default 'src/main/proto'
srcDir
'src/generated'
}
java
{
srcDir
'src/java'
}
}
}
idea
{
module
{
// proto files and generated Java files are automatically added as
// source dirs.
// If you have additional sources, add them here:
sourceDirs
+=
file
(
"/proto/"
);
}
}
signing
{
sign
publishing
.
publications
.
mavenJava
}
javadoc
{
if
(
JavaVersion
.
current
().
isJava9Compatible
())
{
options
.
addBooleanOption
(
'html5'
,
true
)
}
}
\ No newline at end of file
src/main/java/emu/grasscutter/Grasscutter.java
View file @
b9f7c657
...
...
@@ -36,7 +36,7 @@ public final class Grasscutter {
private
static
GameServer
gameServer
;
private
static
PluginManager
pluginManager
;
public
static
final
Reflections
reflector
=
new
Reflections
();
public
static
final
Reflections
reflector
=
new
Reflections
(
"emu.grasscutter"
);
static
{
// Declare logback configuration.
...
...
@@ -70,13 +70,13 @@ public final class Grasscutter {
// Database
DatabaseManager
.
initialize
();
// Create plugin manager instance.
pluginManager
=
new
PluginManager
();
// Create server instances.
dispatchServer
=
new
DispatchServer
();
gameServer
=
new
GameServer
(
new
InetSocketAddress
(
getConfig
().
getGameServerOptions
().
Ip
,
getConfig
().
getGameServerOptions
().
Port
));
// Create plugin manager instance.
pluginManager
=
new
PluginManager
();
// Start servers.
if
(
getConfig
().
RunMode
.
equalsIgnoreCase
(
"HYBRID"
))
{
dispatchServer
.
start
();
...
...
src/main/java/emu/grasscutter/command/Command.java
View file @
b9f7c657
...
...
@@ -14,4 +14,6 @@ public @interface Command {
String
[]
aliases
()
default
{};
String
permission
()
default
""
;
boolean
threading
()
default
false
;
}
src/main/java/emu/grasscutter/command/CommandMap.java
View file @
b9f7c657
...
...
@@ -11,7 +11,6 @@ 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
);
}
...
...
@@ -106,8 +105,9 @@ public final class CommandMap {
*/
public
void
invoke
(
GenshinPlayer
player
,
String
rawMessage
)
{
rawMessage
=
rawMessage
.
trim
();
if
(
rawMessage
.
length
()
==
0
)
{
CommandHandler
.
sendMessage
(
player
,
"No command specified."
);
return
;
if
(
rawMessage
.
length
()
==
0
)
{
CommandHandler
.
sendMessage
(
player
,
"No command specified."
);
return
;
}
// Remove prefix if present.
...
...
@@ -118,7 +118,6 @@ public final class CommandMap {
String
[]
split
=
rawMessage
.
split
(
" "
);
List
<
String
>
args
=
new
LinkedList
<>(
Arrays
.
asList
(
split
));
String
label
=
args
.
remove
(
0
);
// Get command handler.
CommandHandler
handler
=
this
.
commands
.
get
(
label
);
if
(
handler
==
null
)
{
...
...
@@ -130,14 +129,22 @@ public final class CommandMap {
if
(
player
!=
null
)
{
String
permissionNode
=
this
.
annotations
.
get
(
label
).
permission
();
Account
account
=
player
.
getAccount
();
if
(!
permissionNode
.
isEmpty
()
&&
!
account
.
hasPermission
(
permissionNode
))
{
if
(!
permissionNode
.
isEmpty
()
&&
!
account
.
hasPermission
(
permissionNode
))
{
CommandHandler
.
sendMessage
(
player
,
"You do not have permission to run this command."
);
return
;
}
}
// Invoke execute method for handler.
handler
.
execute
(
player
,
args
);
boolean
threading
=
this
.
annotations
.
get
(
label
).
threading
();
Runnable
runnable
=
()
->
handler
.
execute
(
player
,
args
);
if
(
threading
)
{
Thread
command
=
new
Thread
(
runnable
);
command
.
start
();
}
else
{
runnable
.
run
();
}
}
/**
...
...
src/main/java/emu/grasscutter/command/commands/ClearCommand.java
View file @
b9f7c657
...
...
@@ -3,15 +3,10 @@ package emu.grasscutter.command.commands;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.command.Command
;
import
emu.grasscutter.command.CommandHandler
;
import
emu.grasscutter.data.GenshinData
;
import
emu.grasscutter.data.def.ItemData
;
import
emu.grasscutter.game.GenshinPlayer
;
import
emu.grasscutter.game.inventory.GenshinItem
;
import
emu.grasscutter.game.inventory.Inventory
;
import
emu.grasscutter.game.inventory.ItemType
;
import
java.util.Collection
;
import
java.util.LinkedList
;
import
java.util.List
;
@Command
(
label
=
"clear"
,
usage
=
"clear <all|wp|art|mat>"
,
//Merged /clearartifacts and /clearweapons to /clear <args> [uid]
...
...
@@ -33,62 +28,62 @@ public final class ClearCommand implements CommandHandler {
try
{
target
=
Integer
.
parseInt
(
args
.
get
(
0
));
GenshinPlayer
targetPlayer
=
Grasscutter
.
getGameServer
().
getPlayerByUid
(
target
);
if
(
targetPlayer
==
null
&&
sender
!=
null
)
{
if
(
targetPlayer
==
null
)
{
target
=
sender
.
getUid
();
}
else
{
switch
(
cmdSwitch
){
case
"wp"
:
switch
(
cmdSwitch
)
{
case
"wp"
->
{
playerInventory
.
getItems
().
values
().
stream
()
.
filter
(
item
->
item
.
getItemType
()
==
ItemType
.
ITEM_WEAPON
)
.
filter
(
item
->
!
item
.
isLocked
()
&&
!
item
.
isEquipped
())
.
forEach
(
item
->
playerInventory
.
removeItem
(
item
,
item
.
getCount
()));
.
filter
(
item
->
item
.
getItemType
()
==
ItemType
.
ITEM_WEAPON
)
.
filter
(
item
->
!
item
.
isLocked
()
&&
!
item
.
isEquipped
())
.
forEach
(
item
->
playerInventory
.
removeItem
(
item
,
item
.
getCount
()));
sender
.
dropMessage
(
"Cleared weapons for "
+
targetPlayer
.
getNickname
()
+
" ."
);
break
;
case
"art"
:
}
case
"art"
->
{
playerInventory
.
getItems
().
values
().
stream
()
.
filter
(
item
->
item
.
getItemType
()
==
ItemType
.
ITEM_RELIQUARY
)
.
filter
(
item
->
item
.
getLevel
()
==
1
&&
item
.
getExp
()
==
0
)
.
filter
(
item
->
!
item
.
isLocked
()
&&
!
item
.
isEquipped
())
.
forEach
(
item
->
playerInventory
.
removeItem
(
item
,
item
.
getCount
()));
.
filter
(
item
->
item
.
getItemType
()
==
ItemType
.
ITEM_RELIQUARY
)
.
filter
(
item
->
item
.
getLevel
()
==
1
&&
item
.
getExp
()
==
0
)
.
filter
(
item
->
!
item
.
isLocked
()
&&
!
item
.
isEquipped
())
.
forEach
(
item
->
playerInventory
.
removeItem
(
item
,
item
.
getCount
()));
sender
.
dropMessage
(
"Cleared artifacts for "
+
targetPlayer
.
getNickname
()
+
" ."
);
break
;
case
"mat"
:
}
case
"mat"
->
{
playerInventory
.
getItems
().
values
().
stream
()
.
filter
(
item
->
item
.
getItemType
()
==
ItemType
.
ITEM_MATERIAL
)
.
filter
(
item
->
item
.
getLevel
()
==
1
&&
item
.
getExp
()
==
0
)
.
filter
(
item
->
!
item
.
isLocked
()
&&
!
item
.
isEquipped
())
.
forEach
(
item
->
playerInventory
.
removeItem
(
item
,
item
.
getCount
()));
.
filter
(
item
->
item
.
getItemType
()
==
ItemType
.
ITEM_MATERIAL
)
.
filter
(
item
->
item
.
getLevel
()
==
1
&&
item
.
getExp
()
==
0
)
.
filter
(
item
->
!
item
.
isLocked
()
&&
!
item
.
isEquipped
())
.
forEach
(
item
->
playerInventory
.
removeItem
(
item
,
item
.
getCount
()));
sender
.
dropMessage
(
"Cleared artifacts for "
+
targetPlayer
.
getNickname
()
+
" ."
);
break
;
case
"all"
:
}
case
"all"
->
{
playerInventory
.
getItems
().
values
().
stream
()
.
filter
(
item1
->
item1
.
getItemType
()
==
ItemType
.
ITEM_RELIQUARY
)
.
filter
(
item1
->
item1
.
getLevel
()
==
1
&&
item1
.
getExp
()
==
0
)
.
filter
(
item1
->
!
item1
.
isLocked
()
&&
!
item1
.
isEquipped
())
.
forEach
(
item1
->
playerInventory
.
removeItem
(
item1
,
item1
.
getCount
()));
.
filter
(
item1
->
item1
.
getItemType
()
==
ItemType
.
ITEM_RELIQUARY
)
.
filter
(
item1
->
item1
.
getLevel
()
==
1
&&
item1
.
getExp
()
==
0
)
.
filter
(
item1
->
!
item1
.
isLocked
()
&&
!
item1
.
isEquipped
())
.
forEach
(
item1
->
playerInventory
.
removeItem
(
item1
,
item1
.
getCount
()));
playerInventory
.
getItems
().
values
().
stream
()
.
filter
(
item2
->
item2
.
getItemType
()
==
ItemType
.
ITEM_MATERIAL
)
.
filter
(
item2
->
!
item2
.
isLocked
()
&&
!
item2
.
isEquipped
())
.
forEach
(
item2
->
playerInventory
.
removeItem
(
item2
,
item2
.
getCount
()));
.
filter
(
item2
->
item2
.
getItemType
()
==
ItemType
.
ITEM_MATERIAL
)
.
filter
(
item2
->
!
item2
.
isLocked
()
&&
!
item2
.
isEquipped
())
.
forEach
(
item2
->
playerInventory
.
removeItem
(
item2
,
item2
.
getCount
()));
playerInventory
.
getItems
().
values
().
stream
()
.
filter
(
item3
->
item3
.
getItemType
()
==
ItemType
.
ITEM_WEAPON
)
.
filter
(
item3
->
item3
.
getLevel
()
==
1
&&
item3
.
getExp
()
==
0
)
.
filter
(
item3
->
!
item3
.
isLocked
()
&&
!
item3
.
isEquipped
())
.
forEach
(
item3
->
playerInventory
.
removeItem
(
item3
,
item3
.
getCount
()));
.
filter
(
item3
->
item3
.
getItemType
()
==
ItemType
.
ITEM_WEAPON
)
.
filter
(
item3
->
item3
.
getLevel
()
==
1
&&
item3
.
getExp
()
==
0
)
.
filter
(
item3
->
!
item3
.
isLocked
()
&&
!
item3
.
isEquipped
())
.
forEach
(
item3
->
playerInventory
.
removeItem
(
item3
,
item3
.
getCount
()));
playerInventory
.
getItems
().
values
().
stream
()
.
filter
(
item4
->
item4
.
getItemType
()
==
ItemType
.
ITEM_FURNITURE
)
.
filter
(
item4
->
!
item4
.
isLocked
()
&&
!
item4
.
isEquipped
())
.
forEach
(
item4
->
playerInventory
.
removeItem
(
item4
,
item4
.
getCount
()));
.
filter
(
item4
->
item4
.
getItemType
()
==
ItemType
.
ITEM_FURNITURE
)
.
filter
(
item4
->
!
item4
.
isLocked
()
&&
!
item4
.
isEquipped
())
.
forEach
(
item4
->
playerInventory
.
removeItem
(
item4
,
item4
.
getCount
()));
playerInventory
.
getItems
().
values
().
stream
()
.
filter
(
item5
->
item5
.
getItemType
()
==
ItemType
.
ITEM_DISPLAY
)
.
filter
(
item5
->
!
item5
.
isLocked
()
&&
!
item5
.
isEquipped
())
.
forEach
(
item5
->
playerInventory
.
removeItem
(
item5
,
item5
.
getCount
()));
.
filter
(
item5
->
item5
.
getItemType
()
==
ItemType
.
ITEM_DISPLAY
)
.
filter
(
item5
->
!
item5
.
isLocked
()
&&
!
item5
.
isEquipped
())
.
forEach
(
item5
->
playerInventory
.
removeItem
(
item5
,
item5
.
getCount
()));
playerInventory
.
getItems
().
values
().
stream
()
.
filter
(
item6
->
item6
.
getItemType
()
==
ItemType
.
ITEM_VIRTUAL
)
.
filter
(
item6
->
!
item6
.
isLocked
()
&&
!
item6
.
isEquipped
())
.
forEach
(
item6
->
playerInventory
.
removeItem
(
item6
,
item6
.
getCount
()));
.
filter
(
item6
->
item6
.
getItemType
()
==
ItemType
.
ITEM_VIRTUAL
)
.
filter
(
item6
->
!
item6
.
isLocked
()
&&
!
item6
.
isEquipped
())
.
forEach
(
item6
->
playerInventory
.
removeItem
(
item6
,
item6
.
getCount
()));
sender
.
dropMessage
(
"Cleared everything for "
+
targetPlayer
.
getNickname
()
+
" ."
);
break
;
}
}
}
}
catch
(
NumberFormatException
ignored
)
{
...
...
src/main/java/emu/grasscutter/command/commands/GiveAllCommand.java
0 → 100644
View file @
b9f7c657
package
emu.grasscutter.command.commands
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.command.Command
;
import
emu.grasscutter.command.CommandHandler
;
import
emu.grasscutter.data.GenshinData
;
import
emu.grasscutter.data.def.AvatarData
;
import
emu.grasscutter.data.def.ItemData
;
import
emu.grasscutter.game.GenshinPlayer
;
import
emu.grasscutter.game.avatar.GenshinAvatar
;
import
emu.grasscutter.game.inventory.GenshinItem
;
import
emu.grasscutter.game.inventory.ItemType
;
import
java.util.*
;
@Command
(
label
=
"giveall"
,
usage
=
"giveall [player] <amount>"
,
description
=
"Gives all items"
,
aliases
=
{
"givea"
},
permission
=
"player.giveall"
,
threading
=
true
)
public
class
GiveAllCommand
implements
CommandHandler
{
@Override
public
void
execute
(
GenshinPlayer
sender
,
List
<
String
>
args
)
{
int
target
,
amount
=
99999
;
switch
(
args
.
size
())
{
case
0
:
// *no args*
if
(
sender
==
null
)
{
CommandHandler
.
sendMessage
(
null
,
"This usage can only be run in-game"
);
return
;
}
target
=
sender
.
getUid
();
break
;
case
1
:
// [player]
try
{
target
=
Integer
.
parseInt
(
args
.
get
(
0
));
if
(
Grasscutter
.
getGameServer
().
getPlayerByUid
(
target
)
==
null
)
{
CommandHandler
.
sendMessage
(
sender
,
"Invalid player ID."
);
return
;
}
}
catch
(
NumberFormatException
ignored
){
CommandHandler
.
sendMessage
(
sender
,
"Invalid player ID."
);
return
;
}
break
;
case
2
:
// [player] [amount]
try
{
target
=
Integer
.
parseInt
(
args
.
get
(
0
));
if
(
Grasscutter
.
getGameServer
().
getPlayerByUid
(
target
)
==
null
)
{
target
=
sender
.
getUid
();
amount
=
Integer
.
parseInt
(
args
.
get
(
0
));
}
else
{
amount
=
Integer
.
parseInt
(
args
.
get
(
1
));
}
}
catch
(
NumberFormatException
ignored
)
{
CommandHandler
.
sendMessage
(
sender
,
"Invalid amount or player ID."
);
return
;
}
break
;
default
:
// invalid
CommandHandler
.
sendMessage
(
null
,
"Usage: giveall [player] <amount>"
);
return
;
}
GenshinPlayer
targetPlayer
=
Grasscutter
.
getGameServer
().
getPlayerByUid
(
target
);
if
(
targetPlayer
==
null
)
{
CommandHandler
.
sendMessage
(
sender
,
"Player not found."
);
return
;
}
this
.
giveAllItems
(
targetPlayer
,
amount
);
CommandHandler
.
sendMessage
(
sender
,
"Giving all items done"
);
}
public
void
giveAllItems
(
GenshinPlayer
player
,
int
amount
)
{
CommandHandler
.
sendMessage
(
player
,
"Giving all items..."
);
for
(
AvatarData
avatarData:
GenshinData
.
getAvatarDataMap
().
values
())
{
//Exclude test avatar
if
(
isTestAvatar
(
avatarData
.
getId
()))
continue
;
GenshinAvatar
avatar
=
new
GenshinAvatar
(
avatarData
);
avatar
.
setLevel
(
90
);
avatar
.
setPromoteLevel
(
6
);
for
(
int
i
=
1
;
i
<=
6
;
++
i
)
{
avatar
.
getTalentIdList
().
add
((
avatar
.
getAvatarId
()
-
10000000
)
*
10
+
i
);
}
// This will handle stats and talents
avatar
.
recalcStats
();
player
.
addAvatar
(
avatar
);
}
//some test items
List
<
GenshinItem
>
genshinItemList
=
new
ArrayList
<>();
for
(
ItemData
itemdata:
GenshinData
.
getItemDataMap
().
values
())
{
//Exclude test item
if
(
isTestItem
(
itemdata
.
getId
()))
continue
;
if
(
itemdata
.
isEquip
())
{
for
(
int
i
=
0
;
i
<
10
;
++
i
)
{
GenshinItem
genshinItem
=
new
GenshinItem
(
itemdata
);
if
(
itemdata
.
getItemType
()
==
ItemType
.
ITEM_WEAPON
)
{
genshinItem
.
setLevel
(
90
);
genshinItem
.
setPromoteLevel
(
6
);
genshinItem
.
setRefinement
(
4
);
}
genshinItemList
.
add
(
genshinItem
);
}
}
else
{
GenshinItem
genshinItem
=
new
GenshinItem
(
itemdata
);
genshinItem
.
setCount
(
amount
);
genshinItemList
.
add
(
genshinItem
);
}
}
int
packetNum
=
20
;
int
itemLength
=
genshinItemList
.
size
();
int
number
=
itemLength
/
packetNum
;
int
remainder
=
itemLength
%
packetNum
;
int
offset
=
0
;
for
(
int
i
=
0
;
i
<
packetNum
;
++
i
)
{
if
(
remainder
>
0
)
{
player
.
getInventory
().
addItems
(
genshinItemList
.
subList
(
i
*
number
+
offset
,
(
i
+
1
)
*
number
+
offset
+
1
));
--
remainder
;
++
offset
;
}
else
{
player
.
getInventory
().
addItems
(
genshinItemList
.
subList
(
i
*
number
+
offset
,
(
i
+
1
)
*
number
+
offset
));
}
}
}
public
boolean
isTestAvatar
(
int
avatarId
)
{
return
avatarId
<
10000002
||
avatarId
>=
11000000
;
}
public
boolean
isTestItem
(
int
itemId
)
{
for
(
Range
range:
testItemRanges
)
{
if
(
range
.
check
(
itemId
))
{
return
true
;
}
}
if
(
testItemsList
.
contains
(
itemId
))
{
return
true
;
}
return
false
;
}
static
class
Range
{
private
int
min
;
private
int
max
;
public
Range
(
int
min
,
int
max
)
{
if
(
min
>
max
){
min
^=
max
;
max
^=
min
;
min
^=
max
;
}
this
.
min
=
min
;
this
.
max
=
max
;
}
public
boolean
check
(
int
value
)
{
return
value
>=
this
.
min
&&
value
<=
this
.
max
;
}
}
private
static
final
Range
[]
testItemRanges
=
new
Range
[]
{
new
Range
(
106
,
139
),
new
Range
(
1000
,
1099
),
new
Range
(
2001
,
2008
),
new
Range
(
2017
,
2029
),
// new Range(108001, 108387) //food
};
private
static
final
Integer
[]
testItemsIds
=
new
Integer
[]
{
210
,
211
,
314
,
315
,
317
,
1005
,
1007
,
1105
,
1107
,
1201
,
1202
,
2800
,
100001
,
100002
,
100244
,
100305
,
100312
,
100313
,
101212
,
11411
,
11506
,
11507
,
11508
,
12505
,
12506
,
12508
,
12509
,
13503
,
13506
,
14411
,
14503
,
14505
,
14508
,
15411
,
15504
,
15505
,
15506
,
15508
,
20001
,
10002
,
10003
,
10004
,
10005
,
10006
,
10008
//9
};
private
static
final
Collection
<
Integer
>
testItemsList
=
Arrays
.
asList
(
testItemsIds
);
}
src/main/java/emu/grasscutter/command/commands/HealCommand.java
View file @
b9f7c657
...
...
@@ -6,20 +6,19 @@ import emu.grasscutter.game.GenshinPlayer;
import
emu.grasscutter.game.props.FightProperty
;
import
emu.grasscutter.server.packet.send.PacketAvatarFightPropUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketAvatarLifeStateChangeNotify
;
import
emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify
;
import
emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify
;
import
java.util.List
;
@Command
(
label
=
"heal"
,
usage
=
"heal|h"
,
description
=
"Heal all characters in your current team."
,
aliases
=
{
"h"
},
permission
=
"player.heal"
)
public
class
HealCommand
implements
CommandHandler
{
@Command
(
label
=
"heal"
,
usage
=
"heal|h"
,
aliases
=
{
"h"
},
description
=
"Heal all characters in your current team."
,
permission
=
"player.heal"
)
public
final
class
HealCommand
implements
CommandHandler
{
@Override
public
void
execute
(
GenshinPlayer
sender
,
List
<
String
>
args
)
{
if
(
sender
==
null
)
{
CommandHandler
.
sendMessage
(
null
,
"Run this command in-game."
);
return
;
}
sender
.
getTeamManager
().
getActiveTeam
().
forEach
(
entity
->
{
boolean
isAlive
=
entity
.
isAlive
();
entity
.
setFightProperty
(
...
...
@@ -31,6 +30,6 @@ public class HealCommand implements CommandHandler {
entity
.
getWorld
().
broadcastPacket
(
new
PacketAvatarLifeStateChangeNotify
(
entity
.
getAvatar
()));
}
});
CommandHandler
.
sendMessage
(
sender
,
"All characters
are
healed."
);
CommandHandler
.
sendMessage
(
sender
,
"All characters
have been
healed."
);
}
}
src/main/java/emu/grasscutter/command/commands/ListCommand.java
View file @
b9f7c657
...
...
@@ -9,7 +9,7 @@ import java.util.List;
import
java.util.Map
;
@Command
(
label
=
"list"
,
description
=
"List online players"
)
public
class
ListCommand
implements
CommandHandler
{
public
final
class
ListCommand
implements
CommandHandler
{
@Override
public
void
execute
(
GenshinPlayer
sender
,
List
<
String
>
args
)
{
...
...
@@ -19,14 +19,10 @@ public class ListCommand implements CommandHandler {
if
(
playersMap
.
size
()
!=
0
)
{
StringBuilder
playerSet
=
new
StringBuilder
();
for
(
Map
.
Entry
<
Integer
,
GenshinPlayer
>
entry
:
playersMap
.
entrySet
())
{
playerSet
.
append
(
entry
.
getValue
().
getNickname
());
playerSet
.
append
(
", "
);
}
playersMap
.
values
().
forEach
(
player
->
playerSet
.
append
(
player
.
getNickname
()).
append
(
", "
));
String
players
=
playerSet
.
toString
();
CommandHandler
.
sendMessage
(
sender
,
players
.
substring
(
0
,
players
.
length
()
-
2
));
}
}
...
...
src/main/java/emu/grasscutter/command/commands/SetFetterLevelCommand.java
View file @
b9f7c657
...
...
@@ -43,7 +43,7 @@ public final class SetFetterLevelCommand implements CommandHandler {
sender
.
sendPacket
(
new
PacketAvatarFetterDataNotify
(
avatar
));
CommandHandler
.
sendMessage
(
sender
,
"Fetter level set to "
+
fetterLevel
);
}
catch
(
NumberFormatException
ignored
)
{
CommandHandler
.
sendMessage
(
null
,
"Invalid fetter level."
);
CommandHandler
.
sendMessage
(
sender
,
"Invalid fetter level."
);
}
}
...
...
src/main/java/emu/grasscutter/command/commands/TalentCommand.java
View file @
b9f7c657
...
...
@@ -13,7 +13,7 @@ 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
{
public
final
class
TalentCommand
implements
CommandHandler
{
@Override
public
void
execute
(
GenshinPlayer
sender
,
List
<
String
>
args
)
{
...
...
src/main/java/emu/grasscutter/command/commands/Tele
P
ortCommand.java
→
src/main/java/emu/grasscutter/command/commands/Tele
p
ortCommand.java
View file @
b9f7c657
...
...
@@ -9,7 +9,7 @@ import java.util.List;
@Command
(
label
=
"teleport"
,
usage
=
"teleport <x> <y> <z>"
,
aliases
=
{
"tp"
},
description
=
"Change the player's position."
,
permission
=
"player.teleport"
)
public
class
Tele
P
ortCommand
implements
CommandHandler
{
public
final
class
Tele
p
ortCommand
implements
CommandHandler
{
@Override
public
void
execute
(
GenshinPlayer
sender
,
List
<
String
>
args
)
{
...
...
src/main/java/emu/grasscutter/data/ResourceLoader.java
View file @
b9f7c657
...
...
@@ -140,7 +140,7 @@ public class ResourceLoader {
}
List
<
ScenePointEntry
>
scenePointList
=
new
ArrayList
<>();
for
(
File
file
:
folder
.
listFiles
())
{
for
(
File
file
:
Objects
.
requireNonNull
(
folder
.
listFiles
())
)
{
ScenePointConfig
config
=
null
;
Integer
sceneId
=
null
;
...
...
@@ -190,7 +190,7 @@ public class ResourceLoader {
}
else
{
// Load from BinOutput
Pattern
pattern
=
Pattern
.
compile
(
"(?<=ConfigAvatar_)(.*?)(?=.json)"
);
embryoList
=
new
LinkedList
<>();
File
folder
=
new
File
(
Utils
.
toFilePath
(
Grasscutter
.
getConfig
().
RESOURCE_FOLDER
+
"BinOutput/Avatar/"
));
File
[]
files
=
folder
.
listFiles
();
...
...
@@ -198,29 +198,29 @@ public class ResourceLoader {
Grasscutter
.
getLogger
().
error
(
"Error loading ability embryos: no files found in "
+
folder
.
getAbsolutePath
());
return
;
}
for
(
File
file
:
files
)
{
AvatarConfig
config
;
String
avatarName
;
Matcher
matcher
=
pattern
.
matcher
(
file
.
getName
());
if
(
matcher
.
find
())
{
avatarName
=
matcher
.
group
(
0
);
}
else
{
continue
;
}
try
(
FileReader
fileReader
=
new
FileReader
(
file
))
{
config
=
Grasscutter
.
getGsonFactory
().
fromJson
(
fileReader
,
AvatarConfig
.
class
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
continue
;
}
if
(
config
.
abilities
==
null
)
{
continue
;
}
int
s
=
config
.
abilities
.
size
();
AbilityEmbryoEntry
al
=
new
AbilityEmbryoEntry
(
avatarName
,
config
.
abilities
.
stream
().
map
(
Object:
:
toString
).
toArray
(
size
->
new
String
[
s
]));
embryoList
.
add
(
al
);
...
...
@@ -331,7 +331,7 @@ public class ResourceLoader {
GenshinData
.
getOpenConfigEntries
().
put
(
entry
.
getName
(),
entry
);
}
}
// BinOutput configs
private
static
class
AvatarConfig
{
...
...
src/main/java/emu/grasscutter/data/def/CombineData.java
0 → 100644
View file @
b9f7c657
package
emu.grasscutter.data.def
;
import
emu.grasscutter.data.ResourceType
;
@ResourceType
(
name
=
"CombineExcelConfigData.json"
)
public
class
CombineData
{
}
src/main/java/emu/grasscutter/game/GenshinPlayer.java
View file @
b9f7c657
...
...
@@ -31,9 +31,10 @@ import emu.grasscutter.net.proto.InteractTypeOuterClass.InteractType;
import
emu.grasscutter.net.proto.MpSettingTypeOuterClass.MpSettingType
;
import
emu.grasscutter.net.proto.OnlinePlayerInfoOuterClass.OnlinePlayerInfo
;
import
emu.grasscutter.net.proto.PlayerApplyEnterMpReasonOuterClass.PlayerApplyEnterMpReason
;
import
emu.grasscutter.net.proto.PlayerApplyEnterMpResultNotifyOuterClass
;
import
emu.grasscutter.net.proto.PlayerLocationInfoOuterClass.PlayerLocationInfo
;
import
emu.grasscutter.net.proto.PlayerWorldLocationInfoOuterClass
;
import
emu.grasscutter.net.proto.SocialDetailOuterClass.SocialDetail
;
import
emu.grasscutter.net.proto.WorldPlayerLocationInfoOuterClass.WorldPlayerLocationInfo
;
import
emu.grasscutter.server.game.GameServer
;
import
emu.grasscutter.server.game.GameSession
;
import
emu.grasscutter.server.packet.send.PacketAbilityInvocationsNotify
;
...
...
@@ -97,7 +98,7 @@ public class GenshinPlayer {
private
TeamManager
teamManager
;
private
PlayerGachaInfo
gachaInfo
;
private
PlayerProfile
playerProfile
;
private
MpSettingType
mpSetting
=
MpSettingType
.
M
pSettingEnterAfterApply
;
private
MpSettingType
mpSetting
=
MpSettingType
.
M
P_SETTING_ENTER_AFTER_APPLY
;
private
boolean
showAvatar
;
private
ArrayList
<
AvatarProfileData
>
shownAvatars
;
private
Set
<
Integer
>
rewardedLevels
;
...
...
@@ -659,7 +660,7 @@ public class GenshinPlayer {
// Add to inventory
boolean
success
=
getInventory
().
addItem
(
item
);
if
(
success
)
{
this
.
sendPacket
(
new
PacketGadgetInteractRsp
(
drop
,
InteractType
.
I
nteractPickItem
));
this
.
sendPacket
(
new
PacketGadgetInteractRsp
(
drop
,
InteractType
.
I
NTERACT_PICK_ITEM
));
this
.
sendPacket
(
new
PacketItemAddHintNotify
(
item
,
ActionReason
.
SubfieldDrop
));
}
}
...
...
@@ -689,7 +690,7 @@ public class GenshinPlayer {
.
setMpSettingType
(
this
.
getMpSetting
())
.
setNameCardId
(
this
.
getNameCardId
())
.
setSignature
(
this
.
getSignature
())
.
setAvatar
(
HeadImage
.
newBuilder
().
setAvatarId
(
this
.
getHeadImage
()));
.
setAvatar
Id
(
HeadImage
.
newBuilder
().
setAvatarId
(
this
.
getHeadImage
())
.
getAvatarId
()
);
if
(
this
.
getWorld
()
!=
null
)
{
onlineInfo
.
setCurPlayerNumInWorld
(
this
.
getWorld
().
getPlayers
().
indexOf
(
this
)
+
1
);
...
...
@@ -724,21 +725,19 @@ public class GenshinPlayer {
public
SocialDetail
.
Builder
getSocialDetail
()
{
SocialDetail
.
Builder
social
=
SocialDetail
.
newBuilder
()
.
setUid
(
this
.
getUid
())
.
setAvatar
(
HeadImage
.
newBuilder
().
setAvatarId
(
this
.
getHeadImage
()))
.
setAvatar
Id
(
HeadImage
.
newBuilder
().
setAvatarId
(
this
.
getHeadImage
())
.
getAvatarId
()
)
.
setNickname
(
this
.
getNickname
())
.
setSignature
(
this
.
getSignature
())
.
setLevel
(
this
.
getLevel
())
.
setBirthday
(
this
.
getBirthday
().
getFilledProtoWhenNotEmpty
())
.
setWorldLevel
(
this
.
getWorldLevel
())
.
setUnk1
(
1
)
.
setUnk3
(
1
)
.
setNameCardId
(
this
.
getNameCardId
())
.
setFinishAchievementNum
(
0
);
return
social
;
}
public
World
PlayerLocationInfo
getWorldPlayerLocationInfo
()
{
return
World
PlayerLocationInfo
.
newBuilder
()
public
PlayerWorldLocationInfoOuterClass
.
Player
World
LocationInfo
getWorldPlayerLocationInfo
()
{
return
PlayerWorldLocationInfoOuterClass
.
Player
World
LocationInfo
.
newBuilder
()
.
setSceneId
(
this
.
getSceneId
())
.
setPlayerLoc
(
this
.
getPlayerLocationInfo
())
.
build
();
...
...
@@ -763,7 +762,7 @@ public class GenshinPlayer {
while
(
it
.
hasNext
())
{
CoopRequest
req
=
it
.
next
();
if
(
req
.
isExpired
())
{
req
.
getRequester
().
sendPacket
(
new
PacketPlayerApplyEnterMpResultNotify
(
this
,
false
,
PlayerApplyEnterMpRe
ason
.
SystemJudge
));
req
.
getRequester
().
sendPacket
(
new
PacketPlayerApplyEnterMpResultNotify
(
this
,
false
,
PlayerApplyEnterMpRe
sultNotifyOuterClass
.
PlayerApplyEnterMpResultNotify
.
Reason
.
SYSTEM_JUDGE
));
it
.
remove
();
}
}
...
...
src/main/java/emu/grasscutter/game/GenshinScene.java
View file @
b9f7c657
...
...
@@ -202,7 +202,7 @@ public class GenshinScene {
private
void
removePlayerAvatars
(
GenshinPlayer
player
)
{
Iterator
<
EntityAvatar
>
it
=
player
.
getTeamManager
().
getActiveTeam
().
iterator
();
while
(
it
.
hasNext
())
{
this
.
removeEntity
(
it
.
next
(),
VisionType
.
V
isionRemove
);
this
.
removeEntity
(
it
.
next
(),
VisionType
.
V
ISION_REMOVE
);
it
.
remove
();
}
}
...
...
@@ -233,7 +233,7 @@ public class GenshinScene {
this
.
addEntityDirectly
(
entity
);
}
this
.
broadcastPacket
(
new
PacketSceneEntityAppearNotify
(
entities
,
VisionType
.
V
isionBorn
));
this
.
broadcastPacket
(
new
PacketSceneEntityAppearNotify
(
entities
,
VisionType
.
V
ISION_BORN
));
}
private
GenshinEntity
removeEntityDirectly
(
GenshinEntity
entity
)
{
...
...
@@ -241,7 +241,7 @@ public class GenshinScene {
}
public
void
removeEntity
(
GenshinEntity
entity
)
{
this
.
removeEntity
(
entity
,
VisionType
.
V
isionDie
);
this
.
removeEntity
(
entity
,
VisionType
.
V
ISION_DIE
);
}
public
synchronized
void
removeEntity
(
GenshinEntity
entity
,
VisionType
visionType
)
{
...
...
@@ -254,8 +254,8 @@ public class GenshinScene {
public
synchronized
void
replaceEntity
(
EntityAvatar
oldEntity
,
EntityAvatar
newEntity
)
{
this
.
removeEntityDirectly
(
oldEntity
);
this
.
addEntityDirectly
(
newEntity
);
this
.
broadcastPacket
(
new
PacketSceneEntityDisappearNotify
(
oldEntity
,
VisionType
.
V
isionReplace
));
this
.
broadcastPacket
(
new
PacketSceneEntityAppearNotify
(
newEntity
,
VisionType
.
V
isionReplace
,
oldEntity
.
getId
()));
this
.
broadcastPacket
(
new
PacketSceneEntityDisappearNotify
(
oldEntity
,
VisionType
.
V
ISION_REPLACE
));
this
.
broadcastPacket
(
new
PacketSceneEntityAppearNotify
(
newEntity
,
VisionType
.
V
ISION_REPLACE
,
oldEntity
.
getId
()));
}
public
void
showOtherEntities
(
GenshinPlayer
player
)
{
...
...
@@ -269,7 +269,7 @@ public class GenshinScene {
entities
.
add
(
entity
);
}
player
.
sendPacket
(
new
PacketSceneEntityAppearNotify
(
entities
,
VisionType
.
V
isionMeet
));
player
.
sendPacket
(
new
PacketSceneEntityAppearNotify
(
entities
,
VisionType
.
V
ISION_MEET
));
}
public
void
handleAttack
(
AttackResult
result
)
{
...
...
@@ -381,11 +381,11 @@ public class GenshinScene {
if
(
toAdd
.
size
()
>
0
)
{
toAdd
.
stream
().
forEach
(
this
::
addEntityDirectly
);
this
.
broadcastPacket
(
new
PacketSceneEntityAppearNotify
(
toAdd
,
VisionType
.
V
isionBorn
));
this
.
broadcastPacket
(
new
PacketSceneEntityAppearNotify
(
toAdd
,
VisionType
.
V
ISION_BORN
));
}
if
(
toRemove
.
size
()
>
0
)
{
toRemove
.
stream
().
forEach
(
this
::
removeEntityDirectly
);
this
.
broadcastPacket
(
new
PacketSceneEntityDisappearNotify
(
toRemove
,
VisionType
.
V
isionRemove
));
this
.
broadcastPacket
(
new
PacketSceneEntityDisappearNotify
(
toRemove
,
VisionType
.
V
ISION_REMOVE
));
}
}
...
...
@@ -425,7 +425,7 @@ public class GenshinScene {
return
;
}
this
.
broadcastPacketToOthers
(
gadget
.
getOwner
(),
new
PacketSceneEntityDisappearNotify
(
gadget
,
VisionType
.
V
isionDie
));
this
.
broadcastPacketToOthers
(
gadget
.
getOwner
(),
new
PacketSceneEntityDisappearNotify
(
gadget
,
VisionType
.
V
ISION_DIE
));
}
// Broadcasting
...
...
Prev
1
2
3
4
5
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