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
d9fc1595
Commit
d9fc1595
authored
Apr 19, 2022
by
Melledy
Browse files
Refactor some commands and move inventory/team limits to the config
parent
7417a1b6
Changes
39
Show whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/Config.java
View file @
d9fc1595
...
@@ -40,6 +40,13 @@ public final class Config {
...
@@ -40,6 +40,13 @@ public final class Config {
}
}
public
static
class
ServerOptions
{
public
static
class
ServerOptions
{
public
int
InventoryLimitWeapon
=
2000
;
public
int
InventoryLimitRelic
=
2000
;
public
int
InventoryLimitMaterial
=
2000
;
public
int
InventoryLimitFurniture
=
2000
;
public
int
InventoryLimitAll
=
30000
;
public
int
MaxAvatarsInTeam
=
4
;
public
int
MaxAvatarsInTeamMultiplayer
=
4
;
public
int
MaxEntityLimit
=
1000
;
// Max entity limit per world. // TODO: Enforce later.
public
int
MaxEntityLimit
=
1000
;
// Max entity limit per world. // TODO: Enforce later.
public
int
[]
WelcomeEmotes
=
{
2007
,
1002
,
4010
};
public
int
[]
WelcomeEmotes
=
{
2007
,
1002
,
4010
};
public
String
WelcomeMotd
=
"Welcome to Grasscutter emu"
;
public
String
WelcomeMotd
=
"Welcome to Grasscutter emu"
;
...
...
src/main/java/emu/grasscutter/GenshinConstants.java
View file @
d9fc1595
...
@@ -9,14 +9,6 @@ public final class GenshinConstants {
...
@@ -9,14 +9,6 @@ public final class GenshinConstants {
public
static
String
VERSION
=
"2.6.0"
;
public
static
String
VERSION
=
"2.6.0"
;
public
static
final
int
MAX_TEAMS
=
4
;
public
static
final
int
MAX_TEAMS
=
4
;
public
static
final
int
MAX_AVATARS_IN_TEAM
=
4
;
public
static
final
int
LIMIT_WEAPON
=
2000
;
public
static
final
int
LIMIT_RELIC
=
2000
;
public
static
final
int
LIMIT_MATERIAL
=
2000
;
public
static
final
int
LIMIT_FURNITURE
=
2000
;
public
static
final
int
LIMIT_ALL
=
30000
;
public
static
final
int
MAIN_CHARACTER_MALE
=
10000005
;
public
static
final
int
MAIN_CHARACTER_MALE
=
10000005
;
public
static
final
int
MAIN_CHARACTER_FEMALE
=
10000007
;
public
static
final
int
MAIN_CHARACTER_FEMALE
=
10000007
;
public
static
final
Position
START_POSITION
=
new
Position
(
2747
,
194
,
-
1719
);
public
static
final
Position
START_POSITION
=
new
Position
(
2747
,
194
,
-
1719
);
...
...
src/main/java/emu/grasscutter/Grasscutter.java
View file @
d9fc1595
...
@@ -42,6 +42,7 @@ public final class Grasscutter {
...
@@ -42,6 +42,7 @@ public final class Grasscutter {
// Load server configuration.
// Load server configuration.
Grasscutter
.
loadConfig
();
Grasscutter
.
loadConfig
();
// Check server structure.
// Check server structure.
Utils
.
startupCheck
();
Utils
.
startupCheck
();
}
}
...
...
src/main/java/emu/grasscutter/commands/PlayerCommands.java
View file @
d9fc1595
...
@@ -52,8 +52,8 @@ public final class PlayerCommands {
...
@@ -52,8 +52,8 @@ public final class PlayerCommands {
case
2
:
case
2
:
try
{
try
{
target
=
Integer
.
parseInt
(
args
.
get
(
0
));
target
=
Integer
.
parseInt
(
args
.
get
(
0
));
if
(
Grasscutter
.
getGameServer
().
getPlayerBy
I
d
(
target
)
==
null
)
{
if
(
Grasscutter
.
getGameServer
().
getPlayerBy
Ui
d
(
target
)
==
null
)
{
target
=
player
.
get
I
d
();
amount
=
Integer
.
parseInt
(
args
.
get
(
1
));
target
=
player
.
get
Ui
d
();
amount
=
Integer
.
parseInt
(
args
.
get
(
1
));
item
=
Integer
.
parseInt
(
args
.
get
(
0
));
item
=
Integer
.
parseInt
(
args
.
get
(
0
));
}
else
{
}
else
{
item
=
Integer
.
parseInt
(
args
.
get
(
1
));
item
=
Integer
.
parseInt
(
args
.
get
(
1
));
...
@@ -67,7 +67,7 @@ public final class PlayerCommands {
...
@@ -67,7 +67,7 @@ public final class PlayerCommands {
case
3
:
case
3
:
try
{
try
{
target
=
Integer
.
parseInt
(
args
.
get
(
0
));
target
=
Integer
.
parseInt
(
args
.
get
(
0
));
if
(
Grasscutter
.
getGameServer
().
getPlayerBy
I
d
(
target
)
==
null
)
{
if
(
Grasscutter
.
getGameServer
().
getPlayerBy
Ui
d
(
target
)
==
null
)
{
CommandHandler
.
sendMessage
(
player
,
"Invalid player ID."
);
return
;
CommandHandler
.
sendMessage
(
player
,
"Invalid player ID."
);
return
;
}
}
...
@@ -81,7 +81,7 @@ public final class PlayerCommands {
...
@@ -81,7 +81,7 @@ public final class PlayerCommands {
break
;
break
;
}
}
GenshinPlayer
targetPlayer
=
Grasscutter
.
getGameServer
().
getPlayerBy
I
d
(
target
);
GenshinPlayer
targetPlayer
=
Grasscutter
.
getGameServer
().
getPlayerBy
Ui
d
(
target
);
if
(
targetPlayer
==
null
)
{
if
(
targetPlayer
==
null
)
{
CommandHandler
.
sendMessage
(
player
,
"Player not found."
);
return
;
CommandHandler
.
sendMessage
(
player
,
"Player not found."
);
return
;
}
}
...
@@ -108,7 +108,7 @@ public final class PlayerCommands {
...
@@ -108,7 +108,7 @@ public final class PlayerCommands {
int
item
=
Integer
.
parseInt
(
args
.
get
(
1
));
int
item
=
Integer
.
parseInt
(
args
.
get
(
1
));
int
amount
=
1
;
if
(
args
.
size
()
>
2
)
amount
=
Integer
.
parseInt
(
args
.
get
(
2
));
int
amount
=
1
;
if
(
args
.
size
()
>
2
)
amount
=
Integer
.
parseInt
(
args
.
get
(
2
));
GenshinPlayer
targetPlayer
=
Grasscutter
.
getGameServer
().
getPlayerBy
I
d
(
target
);
GenshinPlayer
targetPlayer
=
Grasscutter
.
getGameServer
().
getPlayerBy
Ui
d
(
target
);
if
(
targetPlayer
==
null
)
{
if
(
targetPlayer
==
null
)
{
CommandHandler
.
sendMessage
(
null
,
"Player not found."
);
return
;
CommandHandler
.
sendMessage
(
null
,
"Player not found."
);
return
;
}
}
...
@@ -233,7 +233,7 @@ public final class PlayerCommands {
...
@@ -233,7 +233,7 @@ public final class PlayerCommands {
int
playerUid
=
Integer
.
parseInt
(
args
.
get
(
0
));
int
playerUid
=
Integer
.
parseInt
(
args
.
get
(
0
));
int
sceneId
=
Integer
.
parseInt
(
args
.
get
(
1
));
int
sceneId
=
Integer
.
parseInt
(
args
.
get
(
1
));
GenshinPlayer
player
=
Grasscutter
.
getGameServer
().
getPlayerBy
I
d
(
playerUid
);
GenshinPlayer
player
=
Grasscutter
.
getGameServer
().
getPlayerBy
Ui
d
(
playerUid
);
if
(
player
==
null
)
{
if
(
player
==
null
)
{
CommandHandler
.
sendMessage
(
null
,
"Player not found or offline."
);
CommandHandler
.
sendMessage
(
null
,
"Player not found or offline."
);
return
;
return
;
...
...
src/main/java/emu/grasscutter/commands/ServerCommands.java
View file @
d9fc1595
...
@@ -43,7 +43,7 @@ public final class ServerCommands {
...
@@ -43,7 +43,7 @@ public final class ServerCommands {
int
target
=
Integer
.
parseInt
(
args
.
get
(
0
));
int
target
=
Integer
.
parseInt
(
args
.
get
(
0
));
String
message
=
String
.
join
(
" "
,
args
.
subList
(
1
,
args
.
size
()));
String
message
=
String
.
join
(
" "
,
args
.
subList
(
1
,
args
.
size
()));
GenshinPlayer
targetPlayer
=
Grasscutter
.
getGameServer
().
getPlayerBy
I
d
(
target
);
GenshinPlayer
targetPlayer
=
Grasscutter
.
getGameServer
().
getPlayerBy
Ui
d
(
target
);
if
(
targetPlayer
==
null
)
{
if
(
targetPlayer
==
null
)
{
CommandHandler
.
sendMessage
(
null
,
"Player not found."
);
return
;
CommandHandler
.
sendMessage
(
null
,
"Player not found."
);
return
;
}
}
...
@@ -65,7 +65,7 @@ public final class ServerCommands {
...
@@ -65,7 +65,7 @@ public final class ServerCommands {
int
target
=
Integer
.
parseInt
(
args
.
get
(
0
));
int
target
=
Integer
.
parseInt
(
args
.
get
(
0
));
String
message
=
String
.
join
(
" "
,
args
.
subList
(
1
,
args
.
size
()));
String
message
=
String
.
join
(
" "
,
args
.
subList
(
1
,
args
.
size
()));
GenshinPlayer
targetPlayer
=
Grasscutter
.
getGameServer
().
getPlayerBy
I
d
(
target
);
GenshinPlayer
targetPlayer
=
Grasscutter
.
getGameServer
().
getPlayerBy
Ui
d
(
target
);
if
(
targetPlayer
==
null
)
{
if
(
targetPlayer
==
null
)
{
CommandHandler
.
sendMessage
(
player
,
"Player not found."
);
return
;
CommandHandler
.
sendMessage
(
player
,
"Player not found."
);
return
;
}
}
...
...
src/main/java/emu/grasscutter/database/DatabaseHelper.java
View file @
d9fc1595
...
@@ -124,13 +124,13 @@ public class DatabaseHelper {
...
@@ -124,13 +124,13 @@ public class DatabaseHelper {
int
id
=
0
;
int
id
=
0
;
if
(
reservedId
>
0
&&
!
checkPlayerExists
(
reservedId
))
{
if
(
reservedId
>
0
&&
!
checkPlayerExists
(
reservedId
))
{
id
=
reservedId
;
id
=
reservedId
;
character
.
set
I
d
(
id
);
character
.
set
Ui
d
(
id
);
}
else
{
}
else
{
do
{
do
{
id
=
DatabaseManager
.
getNextId
(
character
);
id
=
DatabaseManager
.
getNextId
(
character
);
}
}
while
(
checkPlayerExists
(
id
));
while
(
checkPlayerExists
(
id
));
character
.
set
I
d
(
id
);
character
.
set
Ui
d
(
id
);
}
}
// Save to database
// Save to database
DatabaseManager
.
getDatastore
().
save
(
character
);
DatabaseManager
.
getDatastore
().
save
(
character
);
...
@@ -160,7 +160,7 @@ public class DatabaseHelper {
...
@@ -160,7 +160,7 @@ public class DatabaseHelper {
}
}
public
static
List
<
GenshinAvatar
>
getAvatars
(
GenshinPlayer
player
)
{
public
static
List
<
GenshinAvatar
>
getAvatars
(
GenshinPlayer
player
)
{
Query
<
GenshinAvatar
>
query
=
DatabaseManager
.
getDatastore
().
createQuery
(
GenshinAvatar
.
class
).
filter
(
"ownerId"
,
player
.
get
I
d
());
Query
<
GenshinAvatar
>
query
=
DatabaseManager
.
getDatastore
().
createQuery
(
GenshinAvatar
.
class
).
filter
(
"ownerId"
,
player
.
get
Ui
d
());
return
query
.
find
().
toList
();
return
query
.
find
().
toList
();
}
}
...
@@ -174,16 +174,16 @@ public class DatabaseHelper {
...
@@ -174,16 +174,16 @@ public class DatabaseHelper {
}
}
public
static
List
<
GenshinItem
>
getInventoryItems
(
GenshinPlayer
player
)
{
public
static
List
<
GenshinItem
>
getInventoryItems
(
GenshinPlayer
player
)
{
Query
<
GenshinItem
>
query
=
DatabaseManager
.
getDatastore
().
createQuery
(
GenshinItem
.
class
).
filter
(
"ownerId"
,
player
.
get
I
d
());
Query
<
GenshinItem
>
query
=
DatabaseManager
.
getDatastore
().
createQuery
(
GenshinItem
.
class
).
filter
(
"ownerId"
,
player
.
get
Ui
d
());
return
query
.
find
().
toList
();
return
query
.
find
().
toList
();
}
}
public
static
List
<
Friendship
>
getFriends
(
GenshinPlayer
player
)
{
public
static
List
<
Friendship
>
getFriends
(
GenshinPlayer
player
)
{
Query
<
Friendship
>
query
=
DatabaseManager
.
getDatastore
().
createQuery
(
Friendship
.
class
).
filter
(
"ownerId"
,
player
.
get
I
d
());
Query
<
Friendship
>
query
=
DatabaseManager
.
getDatastore
().
createQuery
(
Friendship
.
class
).
filter
(
"ownerId"
,
player
.
get
Ui
d
());
return
query
.
find
().
toList
();
return
query
.
find
().
toList
();
}
}
public
static
List
<
Friendship
>
getReverseFriends
(
GenshinPlayer
player
)
{
public
static
List
<
Friendship
>
getReverseFriends
(
GenshinPlayer
player
)
{
Query
<
Friendship
>
query
=
DatabaseManager
.
getDatastore
().
createQuery
(
Friendship
.
class
).
filter
(
"friendId"
,
player
.
get
I
d
());
Query
<
Friendship
>
query
=
DatabaseManager
.
getDatastore
().
createQuery
(
Friendship
.
class
).
filter
(
"friendId"
,
player
.
get
Ui
d
());
return
query
.
find
().
toList
();
return
query
.
find
().
toList
();
}
}
...
...
src/main/java/emu/grasscutter/game/GenshinPlayer.java
View file @
d9fc1595
...
@@ -156,17 +156,17 @@ public class GenshinPlayer {
...
@@ -156,17 +156,17 @@ public class GenshinPlayer {
this
.
getRotation
().
set
(
0
,
307
,
0
);
this
.
getRotation
().
set
(
0
,
307
,
0
);
}
}
public
int
get
I
d
()
{
public
int
get
Ui
d
()
{
return
id
;
return
id
;
}
}
public
void
set
I
d
(
int
id
)
{
public
void
set
Ui
d
(
int
id
)
{
this
.
id
=
id
;
this
.
id
=
id
;
}
}
public
long
getNextGuid
()
{
public
long
getNextG
enshinG
uid
()
{
long
nextId
=
++
this
.
nextGuid
;
long
nextId
=
++
this
.
nextGuid
;
return
((
long
)
this
.
get
I
d
()
<<
32
)
+
nextId
;
return
((
long
)
this
.
get
Ui
d
()
<<
32
)
+
nextId
;
}
}
public
Account
getAccount
()
{
public
Account
getAccount
()
{
...
@@ -175,7 +175,7 @@ public class GenshinPlayer {
...
@@ -175,7 +175,7 @@ public class GenshinPlayer {
public
void
setAccount
(
Account
account
)
{
public
void
setAccount
(
Account
account
)
{
this
.
account
=
account
;
this
.
account
=
account
;
this
.
account
.
setPlayerId
(
get
I
d
());
this
.
account
.
setPlayerId
(
get
Ui
d
());
}
}
public
GameSession
getSession
()
{
public
GameSession
getSession
()
{
...
@@ -560,7 +560,7 @@ public class GenshinPlayer {
...
@@ -560,7 +560,7 @@ public class GenshinPlayer {
}
}
public
void
dropMessage
(
Object
message
)
{
public
void
dropMessage
(
Object
message
)
{
this
.
sendPacket
(
new
PacketPrivateChatNotify
(
GenshinConstants
.
SERVER_CONSOLE_UID
,
get
I
d
(),
message
.
toString
()));
this
.
sendPacket
(
new
PacketPrivateChatNotify
(
GenshinConstants
.
SERVER_CONSOLE_UID
,
get
Ui
d
(),
message
.
toString
()));
}
}
/**
/**
...
@@ -569,7 +569,7 @@ public class GenshinPlayer {
...
@@ -569,7 +569,7 @@ public class GenshinPlayer {
* @param message The message to send.
* @param message The message to send.
*/
*/
public
void
sendMessage
(
GenshinPlayer
sender
,
Object
message
)
{
public
void
sendMessage
(
GenshinPlayer
sender
,
Object
message
)
{
this
.
sendPacket
(
new
PacketPrivateChatNotify
(
sender
.
get
I
d
(),
this
.
get
I
d
(),
message
.
toString
()));
this
.
sendPacket
(
new
PacketPrivateChatNotify
(
sender
.
get
Ui
d
(),
this
.
get
Ui
d
(),
message
.
toString
()));
}
}
public
void
interactWith
(
int
gadgetEntityId
)
{
public
void
interactWith
(
int
gadgetEntityId
)
{
...
@@ -614,7 +614,7 @@ public class GenshinPlayer {
...
@@ -614,7 +614,7 @@ public class GenshinPlayer {
public
OnlinePlayerInfo
getOnlinePlayerInfo
()
{
public
OnlinePlayerInfo
getOnlinePlayerInfo
()
{
OnlinePlayerInfo
.
Builder
onlineInfo
=
OnlinePlayerInfo
.
newBuilder
()
OnlinePlayerInfo
.
Builder
onlineInfo
=
OnlinePlayerInfo
.
newBuilder
()
.
setUid
(
this
.
get
I
d
())
.
setUid
(
this
.
get
Ui
d
())
.
setNickname
(
this
.
getNickname
())
.
setNickname
(
this
.
getNickname
())
.
setPlayerLevel
(
this
.
getLevel
())
.
setPlayerLevel
(
this
.
getLevel
())
.
setMpSettingType
(
this
.
getMpSetting
())
.
setMpSettingType
(
this
.
getMpSetting
())
...
@@ -633,7 +633,7 @@ public class GenshinPlayer {
...
@@ -633,7 +633,7 @@ public class GenshinPlayer {
public
SocialDetail
.
Builder
getSocialDetail
()
{
public
SocialDetail
.
Builder
getSocialDetail
()
{
SocialDetail
.
Builder
social
=
SocialDetail
.
newBuilder
()
SocialDetail
.
Builder
social
=
SocialDetail
.
newBuilder
()
.
setUid
(
this
.
get
I
d
())
.
setUid
(
this
.
get
Ui
d
())
.
setAvatar
(
HeadImage
.
newBuilder
().
setAvatarId
(
this
.
getHeadImage
()))
.
setAvatar
(
HeadImage
.
newBuilder
().
setAvatarId
(
this
.
getHeadImage
()))
.
setNickname
(
this
.
getNickname
())
.
setNickname
(
this
.
getNickname
())
.
setSignature
(
this
.
getSignature
())
.
setSignature
(
this
.
getSignature
())
...
@@ -649,7 +649,7 @@ public class GenshinPlayer {
...
@@ -649,7 +649,7 @@ public class GenshinPlayer {
public
PlayerLocationInfo
getPlayerLocationInfo
()
{
public
PlayerLocationInfo
getPlayerLocationInfo
()
{
return
PlayerLocationInfo
.
newBuilder
()
return
PlayerLocationInfo
.
newBuilder
()
.
setUid
(
this
.
get
I
d
())
.
setUid
(
this
.
get
Ui
d
())
.
setPos
(
this
.
getPos
().
toProto
())
.
setPos
(
this
.
getPos
().
toProto
())
.
setRot
(
this
.
getRotation
().
toProto
())
.
setRot
(
this
.
getRotation
().
toProto
())
.
build
();
.
build
();
...
@@ -699,7 +699,7 @@ public class GenshinPlayer {
...
@@ -699,7 +699,7 @@ public class GenshinPlayer {
// Check if player object exists in server
// Check if player object exists in server
// TODO - optimize
// TODO - optimize
GenshinPlayer
exists
=
this
.
getServer
().
getPlayerBy
I
d
(
get
I
d
());
GenshinPlayer
exists
=
this
.
getServer
().
getPlayerBy
Ui
d
(
get
Ui
d
());
if
(
exists
!=
null
)
{
if
(
exists
!=
null
)
{
exists
.
getSession
().
close
();
exists
.
getSession
().
close
();
}
}
...
...
src/main/java/emu/grasscutter/game/TeamInfo.java
View file @
d9fc1595
...
@@ -4,6 +4,7 @@ import java.util.ArrayList;
...
@@ -4,6 +4,7 @@ import java.util.ArrayList;
import
java.util.List
;
import
java.util.List
;
import
emu.grasscutter.GenshinConstants
;
import
emu.grasscutter.GenshinConstants
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.game.avatar.GenshinAvatar
;
import
emu.grasscutter.game.avatar.GenshinAvatar
;
public
class
TeamInfo
{
public
class
TeamInfo
{
...
@@ -12,7 +13,7 @@ public class TeamInfo {
...
@@ -12,7 +13,7 @@ public class TeamInfo {
public
TeamInfo
()
{
public
TeamInfo
()
{
this
.
name
=
""
;
this
.
name
=
""
;
this
.
avatars
=
new
ArrayList
<>(
G
enshinConstants
.
MAX_AVATARS_IN_TEAM
);
this
.
avatars
=
new
ArrayList
<>(
G
rasscutter
.
getConfig
().
getServerOptions
().
MaxAvatarsInTeam
);
}
}
public
String
getName
()
{
public
String
getName
()
{
...
@@ -36,7 +37,7 @@ public class TeamInfo {
...
@@ -36,7 +37,7 @@ public class TeamInfo {
}
}
public
boolean
addAvatar
(
GenshinAvatar
avatar
)
{
public
boolean
addAvatar
(
GenshinAvatar
avatar
)
{
if
(
size
()
>=
G
enshinConstants
.
MAX_AVATARS_IN_TEAM
||
contains
(
avatar
))
{
if
(
size
()
>=
G
rasscutter
.
getConfig
().
getServerOptions
().
MaxAvatarsInTeam
||
contains
(
avatar
))
{
return
false
;
return
false
;
}
}
...
@@ -56,7 +57,7 @@ public class TeamInfo {
...
@@ -56,7 +57,7 @@ public class TeamInfo {
}
}
public
void
copyFrom
(
TeamInfo
team
)
{
public
void
copyFrom
(
TeamInfo
team
)
{
copyFrom
(
team
,
G
enshinConstants
.
MAX_AVATARS_IN_TEAM
);
copyFrom
(
team
,
G
rasscutter
.
getConfig
().
getServerOptions
().
MaxAvatarsInTeam
);
}
}
public
void
copyFrom
(
TeamInfo
team
,
int
maxTeamSize
)
{
public
void
copyFrom
(
TeamInfo
team
,
int
maxTeamSize
)
{
...
...
src/main/java/emu/grasscutter/game/TeamManager.java
View file @
d9fc1595
...
@@ -10,6 +10,7 @@ import java.util.Set;
...
@@ -10,6 +10,7 @@ import java.util.Set;
import
dev.morphia.annotations.Transient
;
import
dev.morphia.annotations.Transient
;
import
emu.grasscutter.GenshinConstants
;
import
emu.grasscutter.GenshinConstants
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.data.def.AvatarSkillDepotData
;
import
emu.grasscutter.data.def.AvatarSkillDepotData
;
import
emu.grasscutter.game.avatar.GenshinAvatar
;
import
emu.grasscutter.game.avatar.GenshinAvatar
;
import
emu.grasscutter.game.entity.EntityAvatar
;
import
emu.grasscutter.game.entity.EntityAvatar
;
...
@@ -163,12 +164,13 @@ public class TeamManager {
...
@@ -163,12 +164,13 @@ public class TeamManager {
public
int
getMaxTeamSize
()
{
public
int
getMaxTeamSize
()
{
if
(
getPlayer
().
isInMultiplayer
())
{
if
(
getPlayer
().
isInMultiplayer
())
{
int
max
=
Grasscutter
.
getConfig
().
getServerOptions
().
MaxAvatarsInTeamMultiplayer
;
if
(
getPlayer
().
getWorld
().
getHost
()
==
this
.
getPlayer
())
{
if
(
getPlayer
().
getWorld
().
getHost
()
==
this
.
getPlayer
())
{
return
Math
.
max
(
1
,
(
int
)
Math
.
ceil
(
GenshinConstants
.
MAX_AVATARS_IN_TEAM
/
(
double
)
getWorld
().
getPlayerCount
()));
return
Math
.
max
(
1
,
(
int
)
Math
.
ceil
(
max
/
(
double
)
getWorld
().
getPlayerCount
()));
}
}
return
Math
.
max
(
1
,
(
int
)
Math
.
floor
(
GenshinConstants
.
MAX_AVATARS_IN_TEAM
/
(
double
)
getWorld
().
getPlayerCount
()));
return
Math
.
max
(
1
,
(
int
)
Math
.
floor
(
max
/
(
double
)
getWorld
().
getPlayerCount
()));
}
}
return
G
enshinConstants
.
MAX_AVATARS_IN_TEAM
;
return
G
rasscutter
.
getConfig
().
getServerOptions
().
MaxAvatarsInTeam
;
}
}
// Methods
// Methods
...
...
src/main/java/emu/grasscutter/game/avatar/GenshinAvatar.java
View file @
d9fc1595
...
@@ -148,8 +148,8 @@ public class GenshinAvatar {
...
@@ -148,8 +148,8 @@ public class GenshinAvatar {
public
void
setOwner
(
GenshinPlayer
player
)
{
public
void
setOwner
(
GenshinPlayer
player
)
{
this
.
owner
=
player
;
this
.
owner
=
player
;
this
.
ownerId
=
player
.
get
I
d
();
this
.
ownerId
=
player
.
get
Ui
d
();
this
.
guid
=
player
.
getNextGuid
();
this
.
guid
=
player
.
getNextG
enshinG
uid
();
}
}
public
int
getSatiation
()
{
public
int
getSatiation
()
{
...
...
src/main/java/emu/grasscutter/game/entity/EntityAvatar.java
View file @
d9fc1595
...
@@ -107,7 +107,7 @@ public class EntityAvatar extends GenshinEntity {
...
@@ -107,7 +107,7 @@ public class EntityAvatar extends GenshinEntity {
public
SceneAvatarInfo
getSceneAvatarInfo
()
{
public
SceneAvatarInfo
getSceneAvatarInfo
()
{
SceneAvatarInfo
.
Builder
avatarInfo
=
SceneAvatarInfo
.
newBuilder
()
SceneAvatarInfo
.
Builder
avatarInfo
=
SceneAvatarInfo
.
newBuilder
()
.
setPlayerId
(
this
.
getPlayer
().
get
I
d
())
.
setPlayerId
(
this
.
getPlayer
().
get
Ui
d
())
.
setAvatarId
(
this
.
getAvatar
().
getAvatarId
())
.
setAvatarId
(
this
.
getAvatar
().
getAvatarId
())
.
setGuid
(
this
.
getAvatar
().
getGuid
())
.
setGuid
(
this
.
getAvatar
().
getGuid
())
.
setPeerId
(
this
.
getPlayer
().
getPeerId
())
.
setPeerId
(
this
.
getPlayer
().
getPeerId
())
...
...
src/main/java/emu/grasscutter/game/entity/EntityItem.java
View file @
d9fc1595
...
@@ -36,7 +36,7 @@ public class EntityItem extends EntityGadget {
...
@@ -36,7 +36,7 @@ public class EntityItem extends EntityGadget {
this
.
id
=
getScene
().
getWorld
().
getNextEntityId
(
EntityIdType
.
GADGET
);
this
.
id
=
getScene
().
getWorld
().
getNextEntityId
(
EntityIdType
.
GADGET
);
this
.
pos
=
new
Position
(
pos
);
this
.
pos
=
new
Position
(
pos
);
this
.
rot
=
new
Position
();
this
.
rot
=
new
Position
();
this
.
guid
=
player
.
getNextGuid
();
this
.
guid
=
player
.
getNextG
enshinG
uid
();
this
.
item
=
new
GenshinItem
(
itemData
,
count
);
this
.
item
=
new
GenshinItem
(
itemData
,
count
);
}
}
...
...
src/main/java/emu/grasscutter/game/friends/FriendsList.java
View file @
d9fc1595
...
@@ -79,11 +79,11 @@ public class FriendsList {
...
@@ -79,11 +79,11 @@ public class FriendsList {
}
}
// Make sure asker cant do anything
// Make sure asker cant do anything
if
(
myFriendship
.
getAskerId
()
==
this
.
getPlayer
().
get
I
d
())
{
if
(
myFriendship
.
getAskerId
()
==
this
.
getPlayer
().
get
Ui
d
())
{
return
;
return
;
}
}
GenshinPlayer
target
=
getPlayer
().
getSession
().
getServer
().
forceG
etPlayerBy
I
d
(
targetUid
);
GenshinPlayer
target
=
getPlayer
().
getSession
().
getServer
().
g
etPlayerBy
Ui
d
(
targetUid
,
true
);
if
(
target
==
null
)
{
if
(
target
==
null
)
{
return
;
// Should never happen
return
;
// Should never happen
}
}
...
@@ -91,7 +91,7 @@ public class FriendsList {
...
@@ -91,7 +91,7 @@ public class FriendsList {
// Get target's friendship
// Get target's friendship
Friendship
theirFriendship
=
null
;
Friendship
theirFriendship
=
null
;
if
(
target
.
isOnline
())
{
if
(
target
.
isOnline
())
{
theirFriendship
=
target
.
getFriendsList
().
getPendingFriendById
(
this
.
getPlayer
().
get
I
d
());
theirFriendship
=
target
.
getFriendsList
().
getPendingFriendById
(
this
.
getPlayer
().
get
Ui
d
());
}
else
{
}
else
{
theirFriendship
=
DatabaseHelper
.
getReverseFriendship
(
myFriendship
);
theirFriendship
=
DatabaseHelper
.
getReverseFriendship
(
myFriendship
);
}
}
...
@@ -112,7 +112,7 @@ public class FriendsList {
...
@@ -112,7 +112,7 @@ public class FriendsList {
this
.
addFriend
(
myFriendship
);
this
.
addFriend
(
myFriendship
);
if
(
target
.
isOnline
())
{
if
(
target
.
isOnline
())
{
target
.
getFriendsList
().
getPendingFriends
().
remove
(
this
.
getPlayer
().
get
I
d
());
target
.
getFriendsList
().
getPendingFriends
().
remove
(
this
.
getPlayer
().
get
Ui
d
());
target
.
getFriendsList
().
addFriend
(
theirFriendship
);
target
.
getFriendsList
().
addFriend
(
theirFriendship
);
}
}
...
@@ -124,7 +124,7 @@ public class FriendsList {
...
@@ -124,7 +124,7 @@ public class FriendsList {
myFriendship
.
delete
();
myFriendship
.
delete
();
// Delete from target uid
// Delete from target uid
if
(
target
.
isOnline
())
{
if
(
target
.
isOnline
())
{
theirFriendship
=
target
.
getFriendsList
().
getPendingFriendById
(
this
.
getPlayer
().
get
I
d
());
theirFriendship
=
target
.
getFriendsList
().
getPendingFriendById
(
this
.
getPlayer
().
get
Ui
d
());
}
}
theirFriendship
.
delete
();
theirFriendship
.
delete
();
}
}
...
@@ -146,7 +146,7 @@ public class FriendsList {
...
@@ -146,7 +146,7 @@ public class FriendsList {
GenshinPlayer
friend
=
myFriendship
.
getFriendProfile
().
getPlayer
();
GenshinPlayer
friend
=
myFriendship
.
getFriendProfile
().
getPlayer
();
if
(
friend
!=
null
)
{
if
(
friend
!=
null
)
{
// Friend online
// Friend online
theirFriendship
=
friend
.
getFriendsList
().
getFriendById
(
this
.
getPlayer
().
get
I
d
());
theirFriendship
=
friend
.
getFriendsList
().
getFriendById
(
this
.
getPlayer
().
get
Ui
d
());
if
(
theirFriendship
!=
null
)
{
if
(
theirFriendship
!=
null
)
{
friend
.
getFriendsList
().
getFriends
().
remove
(
theirFriendship
.
getFriendId
());
friend
.
getFriendsList
().
getFriends
().
remove
(
theirFriendship
.
getFriendId
());
theirFriendship
.
delete
();
theirFriendship
.
delete
();
...
@@ -165,7 +165,7 @@ public class FriendsList {
...
@@ -165,7 +165,7 @@ public class FriendsList {
}
}
public
synchronized
void
sendFriendRequest
(
int
targetUid
)
{
public
synchronized
void
sendFriendRequest
(
int
targetUid
)
{
GenshinPlayer
target
=
getPlayer
().
getSession
().
getServer
().
forceG
etPlayerBy
I
d
(
targetUid
);
GenshinPlayer
target
=
getPlayer
().
getSession
().
getServer
().
g
etPlayerBy
Ui
d
(
targetUid
,
true
);
if
(
target
==
null
||
target
==
this
.
getPlayer
())
{
if
(
target
==
null
||
target
==
this
.
getPlayer
())
{
return
;
return
;
...
@@ -220,14 +220,14 @@ public class FriendsList {
...
@@ -220,14 +220,14 @@ public class FriendsList {
friendship
.
setOwner
(
getPlayer
());
friendship
.
setOwner
(
getPlayer
());
// Check if friend is online
// Check if friend is online
GenshinPlayer
friend
=
getPlayer
().
getSession
().
getServer
().
getPlayerBy
I
d
(
friendship
.
getFriendProfile
().
getId
());
GenshinPlayer
friend
=
getPlayer
().
getSession
().
getServer
().
getPlayerBy
Ui
d
(
friendship
.
getFriendProfile
().
getId
());
if
(
friend
!=
null
)
{
if
(
friend
!=
null
)
{
// Set friend to online mode
// Set friend to online mode
friendship
.
setFriendProfile
(
friend
);
friendship
.
setFriendProfile
(
friend
);
// Update our status on friend's client if theyre online
// Update our status on friend's client if theyre online
if
(
friend
.
getFriendsList
().
hasLoaded
())
{
if
(
friend
.
getFriendsList
().
hasLoaded
())
{
Friendship
theirFriendship
=
friend
.
getFriendsList
().
getFriendshipById
(
getPlayer
().
get
I
d
());
Friendship
theirFriendship
=
friend
.
getFriendsList
().
getFriendshipById
(
getPlayer
().
get
Ui
d
());
if
(
theirFriendship
!=
null
)
{
if
(
theirFriendship
!=
null
)
{
// Update friend profile
// Update friend profile
theirFriendship
.
setFriendProfile
(
getPlayer
());
theirFriendship
.
setFriendProfile
(
getPlayer
());
...
...
src/main/java/emu/grasscutter/game/friends/Friendship.java
View file @
d9fc1595
...
@@ -27,10 +27,10 @@ public class Friendship {
...
@@ -27,10 +27,10 @@ public class Friendship {
public
Friendship
(
GenshinPlayer
owner
,
GenshinPlayer
friend
,
GenshinPlayer
asker
)
{
public
Friendship
(
GenshinPlayer
owner
,
GenshinPlayer
friend
,
GenshinPlayer
asker
)
{
this
.
setOwner
(
owner
);
this
.
setOwner
(
owner
);
this
.
ownerId
=
owner
.
get
I
d
();
this
.
ownerId
=
owner
.
get
Ui
d
();
this
.
friendId
=
friend
.
get
I
d
();
this
.
friendId
=
friend
.
get
Ui
d
();
this
.
profile
=
friend
.
getProfile
();
this
.
profile
=
friend
.
getProfile
();
this
.
askerId
=
asker
.
get
I
d
();
this
.
askerId
=
asker
.
get
Ui
d
();
}
}
public
GenshinPlayer
getOwner
()
{
public
GenshinPlayer
getOwner
()
{
...
@@ -70,7 +70,7 @@ public class Friendship {
...
@@ -70,7 +70,7 @@ public class Friendship {
}
}
public
void
setFriendProfile
(
GenshinPlayer
character
)
{
public
void
setFriendProfile
(
GenshinPlayer
character
)
{
if
(
character
==
null
||
this
.
friendId
!=
character
.
get
I
d
())
return
;
if
(
character
==
null
||
this
.
friendId
!=
character
.
get
Ui
d
())
return
;
this
.
profile
=
character
.
getProfile
();
this
.
profile
=
character
.
getProfile
();
}
}
...
...
src/main/java/emu/grasscutter/game/friends/PlayerProfile.java
View file @
d9fc1595
...
@@ -22,7 +22,7 @@ public class PlayerProfile {
...
@@ -22,7 +22,7 @@ public class PlayerProfile {
public
PlayerProfile
()
{
}
public
PlayerProfile
()
{
}
public
PlayerProfile
(
GenshinPlayer
player
)
{
public
PlayerProfile
(
GenshinPlayer
player
)
{
this
.
id
=
player
.
get
I
d
();
this
.
id
=
player
.
get
Ui
d
();
this
.
syncWithCharacter
(
player
);
this
.
syncWithCharacter
(
player
);
}
}
...
...
src/main/java/emu/grasscutter/game/inventory/GenshinItem.java
View file @
d9fc1595
...
@@ -125,8 +125,8 @@ public class GenshinItem {
...
@@ -125,8 +125,8 @@ public class GenshinItem {
}
}
public
void
setOwner
(
GenshinPlayer
player
)
{
public
void
setOwner
(
GenshinPlayer
player
)
{
this
.
ownerId
=
player
.
get
I
d
();
this
.
ownerId
=
player
.
get
Ui
d
();
this
.
guid
=
player
.
getNextGuid
();
this
.
guid
=
player
.
getNextG
enshinG
uid
();
}
}
public
int
getItemId
()
{
public
int
getItemId
()
{
return
itemId
;
return
itemId
;
...
...
src/main/java/emu/grasscutter/game/inventory/Inventory.java
View file @
d9fc1595
...
@@ -6,6 +6,7 @@ import java.util.LinkedList;
...
@@ -6,6 +6,7 @@ import java.util.LinkedList;
import
java.util.List
;
import
java.util.List
;
import
emu.grasscutter.GenshinConstants
;
import
emu.grasscutter.GenshinConstants
;
import
emu.grasscutter.Grasscutter
;
import
emu.grasscutter.data.GenshinData
;
import
emu.grasscutter.data.GenshinData
;
import
emu.grasscutter.data.def.AvatarCostumeData
;
import
emu.grasscutter.data.def.AvatarCostumeData
;
import
emu.grasscutter.data.def.AvatarData
;
import
emu.grasscutter.data.def.AvatarData
;
...
@@ -36,10 +37,10 @@ public class Inventory implements Iterable<GenshinItem> {
...
@@ -36,10 +37,10 @@ public class Inventory implements Iterable<GenshinItem> {
this
.
store
=
new
Long2ObjectOpenHashMap
<>();
this
.
store
=
new
Long2ObjectOpenHashMap
<>();
this
.
inventoryTypes
=
new
Int2ObjectOpenHashMap
<>();
this
.
inventoryTypes
=
new
Int2ObjectOpenHashMap
<>();
this
.
createInventoryTab
(
ItemType
.
ITEM_WEAPON
,
new
EquipInventoryTab
(
G
enshinConstants
.
LIMIT_WEAPON
));
this
.
createInventoryTab
(
ItemType
.
ITEM_WEAPON
,
new
EquipInventoryTab
(
G
rasscutter
.
getConfig
().
getServerOptions
().
InventoryLimitWeapon
));
this
.
createInventoryTab
(
ItemType
.
ITEM_RELIQUARY
,
new
EquipInventoryTab
(
G
enshinConstants
.
LIMIT_RELIC
));
this
.
createInventoryTab
(
ItemType
.
ITEM_RELIQUARY
,
new
EquipInventoryTab
(
G
rasscutter
.
getConfig
().
getServerOptions
().
InventoryLimitRelic
));
this
.
createInventoryTab
(
ItemType
.
ITEM_MATERIAL
,
new
MaterialInventoryTab
(
G
enshinConstants
.
LIMIT_MATERIAL
));
this
.
createInventoryTab
(
ItemType
.
ITEM_MATERIAL
,
new
MaterialInventoryTab
(
G
rasscutter
.
getConfig
().
getServerOptions
().
InventoryLimitMaterial
));
this
.
createInventoryTab
(
ItemType
.
ITEM_FURNITURE
,
new
MaterialInventoryTab
(
G
enshinConstants
.
LIMIT_FURNITURE
));
this
.
createInventoryTab
(
ItemType
.
ITEM_FURNITURE
,
new
MaterialInventoryTab
(
G
rasscutter
.
getConfig
().
getServerOptions
().
InventoryLimitFurniture
));
}
}
public
GenshinPlayer
getPlayer
()
{
public
GenshinPlayer
getPlayer
()
{
...
...
src/main/java/emu/grasscutter/game/managers/ChatManager.java
View file @
d9fc1595
...
@@ -36,14 +36,14 @@ public class ChatManager {
...
@@ -36,14 +36,14 @@ public class ChatManager {
}
}
// Get target
// Get target
GenshinPlayer
target
=
getServer
().
getPlayerBy
I
d
(
targetUid
);
GenshinPlayer
target
=
getServer
().
getPlayerBy
Ui
d
(
targetUid
);
if
(
target
==
null
)
{
if
(
target
==
null
)
{
return
;
return
;
}
}
// Create chat packet
// Create chat packet
GenshinPacket
packet
=
new
PacketPrivateChatNotify
(
player
.
get
I
d
(),
target
.
get
I
d
(),
message
);
GenshinPacket
packet
=
new
PacketPrivateChatNotify
(
player
.
get
Ui
d
(),
target
.
get
Ui
d
(),
message
);
player
.
sendPacket
(
packet
);
player
.
sendPacket
(
packet
);
target
.
sendPacket
(
packet
);
target
.
sendPacket
(
packet
);
...
@@ -51,14 +51,14 @@ public class ChatManager {
...
@@ -51,14 +51,14 @@ public class ChatManager {
public
void
sendPrivateMessage
(
GenshinPlayer
player
,
int
targetUid
,
int
emote
)
{
public
void
sendPrivateMessage
(
GenshinPlayer
player
,
int
targetUid
,
int
emote
)
{
// Get target
// Get target
GenshinPlayer
target
=
getServer
().
getPlayerBy
I
d
(
targetUid
);
GenshinPlayer
target
=
getServer
().
getPlayerBy
Ui
d
(
targetUid
);
if
(
target
==
null
)
{
if
(
target
==
null
)
{
return
;
return
;
}
}
// Create chat packet
// Create chat packet
GenshinPacket
packet
=
new
PacketPrivateChatNotify
(
player
.
get
I
d
(),
target
.
get
I
d
(),
emote
);
GenshinPacket
packet
=
new
PacketPrivateChatNotify
(
player
.
get
Ui
d
(),
target
.
get
Ui
d
(),
emote
);
player
.
sendPacket
(
packet
);
player
.
sendPacket
(
packet
);
target
.
sendPacket
(
packet
);
target
.
sendPacket
(
packet
);
...
...
src/main/java/emu/grasscutter/game/managers/MultiplayerManager.java
View file @
d9fc1595
...
@@ -24,7 +24,7 @@ public class MultiplayerManager {
...
@@ -24,7 +24,7 @@ public class MultiplayerManager {
}
}
public
void
applyEnterMp
(
GenshinPlayer
player
,
int
targetUid
)
{
public
void
applyEnterMp
(
GenshinPlayer
player
,
int
targetUid
)
{
GenshinPlayer
target
=
getServer
().
getPlayerBy
I
d
(
targetUid
);
GenshinPlayer
target
=
getServer
().
getPlayerBy
Ui
d
(
targetUid
);
if
(
target
==
null
)
{
if
(
target
==
null
)
{
player
.
sendPacket
(
new
PacketPlayerApplyEnterMpResultNotify
(
targetUid
,
""
,
false
,
PlayerApplyEnterMpReason
.
PlayerCannotEnterMp
));
player
.
sendPacket
(
new
PacketPlayerApplyEnterMpResultNotify
(
targetUid
,
""
,
false
,
PlayerApplyEnterMpReason
.
PlayerCannotEnterMp
));
return
;
return
;
...
@@ -43,7 +43,7 @@ public class MultiplayerManager {
...
@@ -43,7 +43,7 @@ public class MultiplayerManager {
*/
*/
// Get request
// Get request
CoopRequest
request
=
target
.
getCoopRequests
().
get
(
player
.
get
I
d
());
CoopRequest
request
=
target
.
getCoopRequests
().
get
(
player
.
get
Ui
d
());
if
(
request
!=
null
&&
!
request
.
isExpired
())
{
if
(
request
!=
null
&&
!
request
.
isExpired
())
{
// Join request already exists
// Join request already exists
...
@@ -52,7 +52,7 @@ public class MultiplayerManager {
...
@@ -52,7 +52,7 @@ public class MultiplayerManager {
// Put request in
// Put request in
request
=
new
CoopRequest
(
player
);
request
=
new
CoopRequest
(
player
);
target
.
getCoopRequests
().
put
(
player
.
get
I
d
(),
request
);
target
.
getCoopRequests
().
put
(
player
.
get
Ui
d
(),
request
);
// Packet
// Packet
target
.
sendPacket
(
new
PacketPlayerApplyEnterMpNotify
(
player
));
target
.
sendPacket
(
new
PacketPlayerApplyEnterMpNotify
(
player
));
...
@@ -137,7 +137,7 @@ public class MultiplayerManager {
...
@@ -137,7 +137,7 @@ public class MultiplayerManager {
}
}
// Get victim and sanity checks
// Get victim and sanity checks
GenshinPlayer
victim
=
player
.
getServer
().
getPlayerBy
I
d
(
targetUid
);
GenshinPlayer
victim
=
player
.
getServer
().
getPlayerBy
Ui
d
(
targetUid
);
if
(
victim
==
null
||
victim
==
player
)
{
if
(
victim
==
null
||
victim
==
player
)
{
return
false
;
return
false
;
...
...
src/main/java/emu/grasscutter/server/game/GameServer.java
View file @
d9fc1595
...
@@ -104,21 +104,25 @@ public final class GameServer extends MihoyoKcpServer {
...
@@ -104,21 +104,25 @@ public final class GameServer extends MihoyoKcpServer {
}
}
public
void
registerPlayer
(
GenshinPlayer
player
)
{
public
void
registerPlayer
(
GenshinPlayer
player
)
{
getPlayers
().
put
(
player
.
get
I
d
(),
player
);
getPlayers
().
put
(
player
.
get
Ui
d
(),
player
);
}
}
public
GenshinPlayer
getPlayerBy
I
d
(
int
id
)
{
public
GenshinPlayer
getPlayerBy
Ui
d
(
int
id
)
{
return
this
.
getPlayer
s
().
get
(
id
);
return
this
.
getPlayer
ByUid
(
id
,
false
);
}
}
public
GenshinPlayer
forceG
etPlayerBy
I
d
(
int
id
)
{
public
GenshinPlayer
g
etPlayerBy
Ui
d
(
int
id
,
boolean
allowOfflinePlayers
)
{
// Console check
// Console check
if
(
id
==
GenshinConstants
.
SERVER_CONSOLE_UID
)
{
if
(
id
==
GenshinConstants
.
SERVER_CONSOLE_UID
)
{
return
null
;
return
null
;
}
}
// Get from online players
// Get from online players
GenshinPlayer
player
=
this
.
getPlayerById
(
id
);
GenshinPlayer
player
=
this
.
getPlayerByUid
(
id
);
if
(!
allowOfflinePlayers
)
{
return
player
;
}
// Check database if character isnt here
// Check database if character isnt here
if
(
player
==
null
)
{
if
(
player
==
null
)
{
...
@@ -128,9 +132,9 @@ public final class GameServer extends MihoyoKcpServer {
...
@@ -128,9 +132,9 @@ public final class GameServer extends MihoyoKcpServer {
return
player
;
return
player
;
}
}
public
SocialDetail
.
Builder
getSocialDetailBy
I
d
(
int
id
)
{
public
SocialDetail
.
Builder
getSocialDetailBy
Ui
d
(
int
id
)
{
// Get from online players
// Get from online players
GenshinPlayer
player
=
this
.
forceG
etPlayerBy
I
d
(
id
);
GenshinPlayer
player
=
this
.
g
etPlayerBy
Ui
d
(
id
,
true
);
if
(
player
==
null
)
{
if
(
player
==
null
)
{
return
null
;
return
null
;
...
...
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