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
c2e620bf
Unverified
Commit
c2e620bf
authored
Sep 28, 2022
by
Luke H-W
Committed by
GitHub
Sep 28, 2022
Browse files
[BREAKING] Deobfuscate codex field, slight refactor (#1809)
* Deobfuscate codex field, slight refactor * Fix relic sets in codex
parent
5ffc07cf
Changes
4
Hide whitespace changes
Inline
Side-by-side
src/main/java/emu/grasscutter/data/excels/CodexAnimalData.java
View file @
c2e620bf
package
emu.grasscutter.data.excels
;
import
com.google.gson.annotations.SerializedName
;
import
emu.grasscutter.data.GameResource
;
import
emu.grasscutter.data.ResourceType
;
import
lombok.Getter
;
@ResourceType
(
name
=
{
"AnimalCodexExcelConfigData.json"
})
public
class
CodexAnimalData
extends
GameResource
{
private
int
Id
;
private
String
type
;
private
int
describeId
;
private
int
sortOrder
;
private
CodexAnimalUnlockCondition
OCCLHPBCDGL
;
@Getter
private
String
type
;
@Getter
private
int
describeId
;
@Getter
private
int
sortOrder
;
@SerializedName
(
value
=
"countType"
,
alternate
={
"OCCLHPBCDGL"
})
@Getter
private
CountType
countType
;
@Override
public
int
getId
()
{
return
Id
;
}
public
String
getType
()
{
return
type
;
}
public
int
getDescribeId
()
{
return
describeId
;
}
public
int
getSortOrder
()
{
return
sortOrder
;
}
public
CodexAnimalUnlockCondition
getUnlockCondition
()
{
return
OCCLHPBCDGL
;
}
public
enum
CodexAnimalUnlockCondition
{
public
enum
CountType
{
CODEX_COUNT_TYPE_KILL
,
CODEX_COUNT_TYPE_CAPTURE
}
...
...
src/main/java/emu/grasscutter/data/excels/CodexReliquaryData.java
View file @
c2e620bf
...
...
@@ -3,57 +3,44 @@ package emu.grasscutter.data.excels;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.GameResource
;
import
emu.grasscutter.data.ResourceType
;
import
it.unimi.dsi.fastutil.ints.IntCollection
;
import
it.unimi.dsi.fastutil.ints.IntList
;
import
lombok.Getter
;
@ResourceType
(
name
=
{
"ReliquaryCodexExcelConfigData.json"
})
public
class
CodexReliquaryData
extends
GameResource
{
private
int
Id
;
private
int
suitId
;
private
int
level
;
private
int
cupId
;
private
int
leatherId
;
private
int
capId
;
private
int
flowerId
;
private
int
sandId
;
private
int
sortOrder
;
@Getter
private
int
Id
;
@Getter
private
int
suitId
;
@Getter
private
int
level
;
@Getter
private
int
cupId
;
@Getter
private
int
leatherId
;
@Getter
private
int
capId
;
@Getter
private
int
flowerId
;
@Getter
private
int
sandId
;
@Getter
private
int
sortOrder
;
private
transient
IntCollection
ids
;
public
int
getSortOrder
(
)
{
return
sortOrder
;
public
boolean
containsId
(
int
id
)
{
return
getIds
().
contains
(
id
)
;
}
public
int
getId
()
{
return
Id
;
}
public
int
getSuitId
()
{
return
suitId
;
}
public
int
getLevel
()
{
return
level
;
}
public
int
getCupId
()
{
return
cupId
;
}
public
int
getLeatherId
()
{
return
leatherId
;
}
public
int
getCapId
()
{
return
capId
;
}
public
int
getFlowerId
()
{
return
flowerId
;
}
public
int
getSandId
()
{
return
sandId
;
public
IntCollection
getIds
()
{
if
(
this
.
ids
==
null
)
{
int
[]
idsArr
=
{
cupId
,
leatherId
,
capId
,
flowerId
,
sandId
};
this
.
ids
=
IntList
.
of
(
idsArr
);
}
return
this
.
ids
;
}
@Override
public
void
onLoad
()
{
// Normalize all itemIds to the 0-substat form
cupId
=
(
cupId
/
10
)
*
10
;
leatherId
=
(
leatherId
/
10
)
*
10
;
capId
=
(
capId
/
10
)
*
10
;
flowerId
=
(
flowerId
/
10
)
*
10
;
sandId
=
(
sandId
/
10
)
*
10
;
GameData
.
getcodexReliquaryArrayList
().
add
(
this
);
GameData
.
getcodexReliquaryIdMap
().
put
(
getSuitId
(),
this
);
}
...
...
src/main/java/emu/grasscutter/game/player/PlayerCodex.java
View file @
c2e620bf
...
...
@@ -4,13 +4,12 @@ import dev.morphia.annotations.Entity;
import
dev.morphia.annotations.Transient
;
import
emu.grasscutter.data.GameData
;
import
emu.grasscutter.data.excels.CodexAnimalData
;
import
emu.grasscutter.data.excels.CodexReliquaryData
;
import
emu.grasscutter.game.entity.EntityMonster
;
import
emu.grasscutter.game.entity.GameEntity
;
import
emu.grasscutter.game.inventory.GameItem
;
import
emu.grasscutter.game.inventory.ItemType
;
import
emu.grasscutter.game.inventory.MaterialType
;
import
emu.grasscutter.server.packet.send.PacketCodexDataUpdateNotify
;
import
lombok.Getter
;
import
lombok.val
;
import
java.util.*
;
...
...
@@ -19,14 +18,14 @@ public class PlayerCodex {
@Transient
private
Player
player
;
//itemId is not codexId!
private
Set
<
Integer
>
unlockedWeapon
;
private
Map
<
Integer
,
Integer
>
unlockedAnimal
;
private
Set
<
Integer
>
unlockedMaterial
;
private
Set
<
Integer
>
unlockedBook
;
private
Set
<
Integer
>
unlockedTip
;
private
Set
<
Integer
>
unlockedView
;
private
Set
<
Integer
>
unlockedReliquary
;
private
Set
<
Integer
>
unlockedReliquarySuitCodex
;
@Getter
private
Set
<
Integer
>
unlockedWeapon
;
@Getter
private
Map
<
Integer
,
Integer
>
unlockedAnimal
;
@Getter
private
Set
<
Integer
>
unlockedMaterial
;
@Getter
private
Set
<
Integer
>
unlockedBook
;
@Getter
private
Set
<
Integer
>
unlockedTip
;
@Getter
private
Set
<
Integer
>
unlockedView
;
@Getter
private
Set
<
Integer
>
unlockedReliquary
;
@Getter
private
Set
<
Integer
>
unlockedReliquarySuitCodex
;
public
PlayerCodex
(){
this
.
unlockedWeapon
=
new
HashSet
<>();
...
...
@@ -46,120 +45,86 @@ public class PlayerCodex {
public
void
setPlayer
(
Player
player
)
{
this
.
player
=
player
;
this
.
fixReliquaries
();
}
public
void
checkAddedItem
(
GameItem
item
){
ItemType
type
=
item
.
getItemData
().
getItemType
();
if
(
type
==
ItemType
.
ITEM_WEAPON
){
if
(!
getUnlockedWeapon
().
contains
(
item
.
getItemId
())){
getUnlockedWeapon
().
add
(
item
.
getItemId
());
var
codexItem
=
GameData
.
getCodexWeaponDataIdMap
().
get
(
item
.
getItemId
());
if
(
codexItem
!=
null
){
player
.
save
();
this
.
player
.
sendPacket
(
new
PacketCodexDataUpdateNotify
(
2
,
codexItem
.
getId
()));
}
val
itemData
=
item
.
getItemData
();
val
itemId
=
item
.
getItemId
();
switch
(
itemData
.
getItemType
())
{
case
ITEM_WEAPON
->
{
Optional
.
ofNullable
(
GameData
.
getCodexWeaponDataIdMap
().
get
(
itemId
))
.
ifPresent
(
codexData
->
{
if
(
this
.
getUnlockedWeapon
().
add
(
itemId
))
{
this
.
player
.
save
();
this
.
player
.
sendPacket
(
new
PacketCodexDataUpdateNotify
(
2
,
codexData
.
getId
()));
}
});
}
}
else
if
(
type
==
ItemType
.
ITEM_MATERIAL
){
if
(
item
.
getItemData
().
getMaterialType
()
==
MaterialType
.
MATERIAL_FOOD
||
item
.
getItemData
().
getMaterialType
()
==
MaterialType
.
MATERIAL_WIDGET
||
item
.
getItemData
().
getMaterialType
()
==
MaterialType
.
MATERIAL_EXCHANGE
||
item
.
getItemData
().
getMaterialType
()
==
MaterialType
.
MATERIAL_AVATAR_MATERIAL
||
item
.
getItemData
().
getMaterialType
()
==
MaterialType
.
MATERIAL_NOTICE_ADD_HP
){
if
(!
getUnlockedMaterial
().
contains
(
item
.
getItemId
()))
{
var
codexMaterial
=
GameData
.
getCodexMaterialDataIdMap
().
get
(
item
.
getItemId
());
if
(
codexMaterial
!=
null
)
{
getUnlockedMaterial
().
add
(
item
.
getItemId
());
player
.
save
();
this
.
player
.
sendPacket
(
new
PacketCodexDataUpdateNotify
(
4
,
codexMaterial
.
getId
()));
case
ITEM_MATERIAL
->
{
switch
(
itemData
.
getMaterialType
())
{
// Is this check even needed?
case
MATERIAL_FOOD
,
MATERIAL_WIDGET
,
MATERIAL_EXCHANGE
,
MATERIAL_AVATAR_MATERIAL
,
MATERIAL_NOTICE_ADD_HP
->
{
Optional
.
ofNullable
(
GameData
.
getCodexMaterialDataIdMap
().
get
(
itemId
))
.
ifPresent
(
codexData
->
{
if
(
this
.
getUnlockedMaterial
().
add
(
itemId
))
{
this
.
player
.
save
();
this
.
player
.
sendPacket
(
new
PacketCodexDataUpdateNotify
(
4
,
codexData
.
getId
()));
}
});
}
default
->
{}
}
}
}
else
if
(
type
==
ItemType
.
ITEM_RELIQUARY
)
{
if
(!
getUnlockedReliquary
().
contains
(
item
.
getItemId
())){
getUnlockedReliquary
().
add
(
item
.
getItemId
());
checkUnlockedSuits
(
item
);
case
ITEM_RELIQUARY
->
{
val
reliquaryId
=
(
itemId
/
10
)
*
10
;
// Normalize to 0-substat form
if
(
this
.
getUnlockedReliquary
().
add
(
reliquaryId
))
checkUnlockedSuits
(
reliquaryId
);
}
default
->
{}
}
}
public
void
checkAnimal
(
GameEntity
target
,
CodexAnimalData
.
CodexAnimalUnlockCondition
condition
){
if
(
target
instanceof
EntityMonster
){
var
monsterId
=
((
EntityMonster
)
target
).
getMonsterData
().
getId
();
var
codexAnimal
=
GameData
.
getCodexAnimalDataMap
().
get
(
monsterId
);
public
void
checkAnimal
(
GameEntity
target
,
CodexAnimalData
.
CountType
countType
){
if
(
target
instanceof
EntityMonster
)
{
val
monsterId
=
((
EntityMonster
)
target
).
getMonsterData
().
getId
();
val
codexAnimal
=
GameData
.
getCodexAnimalDataMap
().
get
(
monsterId
);
if
(
codexAnimal
==
null
)
return
;
val
animalCountType
=
codexAnimal
.
getCountType
();
if
(
animalCountType
!=
countType
&&
animalCountType
!=
null
)
return
;
this
.
getUnlockedAnimal
().
merge
(
monsterId
,
1
,
(
i
,
j
)
->
i
+
1
);
if
(!
getUnlockedAnimal
().
containsKey
(
monsterId
))
{
if
(
codexAnimal
!=
null
)
{
if
(
codexAnimal
.
getUnlockCondition
()
==
condition
||
codexAnimal
.
getUnlockCondition
()
==
null
){
getUnlockedAnimal
().
put
(
monsterId
,
1
);
}
}
}
else
{
getUnlockedAnimal
().
put
(
monsterId
,
getUnlockedAnimal
().
get
(
monsterId
)
+
1
);
}
player
.
save
();
this
.
player
.
sendPacket
(
new
PacketCodexDataUpdateNotify
(
3
,
monsterId
));
}
}
public
void
checkUnlockedSuits
(
GameItem
item
){
int
reliquaryId
=
item
.
getItemId
();
Optional
<
CodexReliquaryData
>
excelReliquarySuitList
=
GameData
.
getcodexReliquaryArrayList
().
stream
().
filter
(
x
->
x
.
getCupId
()
==
reliquaryId
||
x
.
getLeatherId
()
==
reliquaryId
||
x
.
getCapId
()
==
reliquaryId
||
x
.
getFlowerId
()
==
reliquaryId
||
x
.
getSandId
()
==
reliquaryId
).
findFirst
();
if
(
excelReliquarySuitList
.
isPresent
())
{
var
excelReliquarySuit
=
excelReliquarySuitList
.
get
();
if
(!
getUnlockedReliquarySuitCodex
().
contains
(
excelReliquarySuit
.
getId
())){
if
(
getUnlockedReliquary
().
contains
(
excelReliquarySuit
.
getCupId
())
&&
getUnlockedReliquary
().
contains
(
excelReliquarySuit
.
getLeatherId
())
&&
getUnlockedReliquary
().
contains
(
excelReliquarySuit
.
getCapId
())
&&
getUnlockedReliquary
().
contains
(
excelReliquarySuit
.
getFlowerId
())
&&
getUnlockedReliquary
().
contains
(
excelReliquarySuit
.
getSandId
())
){
getUnlockedReliquarySuitCodex
().
add
(
excelReliquarySuit
.
getId
());
player
.
save
();
this
.
player
.
sendPacket
(
new
PacketCodexDataUpdateNotify
(
8
,
excelReliquarySuit
.
getId
()));
}
}
}
}
public
Set
<
Integer
>
getUnlockedWeapon
()
{
return
unlockedWeapon
;
public
void
checkUnlockedSuits
(
int
reliquaryId
){
GameData
.
getcodexReliquaryArrayList
().
stream
()
.
filter
(
x
->
!
this
.
getUnlockedReliquarySuitCodex
().
contains
(
x
.
getId
()))
.
filter
(
x
->
x
.
containsId
(
reliquaryId
))
.
filter
(
x
->
this
.
getUnlockedReliquary
().
containsAll
(
x
.
getIds
()))
.
forEach
(
x
->
{
int
id
=
x
.
getId
();
this
.
getUnlockedReliquarySuitCodex
().
add
(
id
);
this
.
player
.
save
();
this
.
player
.
sendPacket
(
new
PacketCodexDataUpdateNotify
(
8
,
id
));
});
}
public
Map
<
Integer
,
Integer
>
getUnlockedAnimal
()
{
return
unlockedAnimal
;
@Deprecated
// Maybe remove this if we ever stop caring about older dbs
private
void
fixReliquaries
()
{
// Migrate older database entries which were using non-canonical forms of itemIds
val
newReliquaries
=
new
HashSet
<
Integer
>();
this
.
unlockedReliquary
.
forEach
(
i
->
newReliquaries
.
add
((
i
/
10
)*
10
));
this
.
unlockedReliquary
=
newReliquaries
;
GameData
.
getcodexReliquaryArrayList
().
stream
()
.
filter
(
x
->
!
this
.
getUnlockedReliquarySuitCodex
().
contains
(
x
.
getId
()))
.
filter
(
x
->
this
.
getUnlockedReliquary
().
containsAll
(
x
.
getIds
()))
.
forEach
(
x
->
this
.
getUnlockedReliquarySuitCodex
().
add
(
x
.
getId
()));
this
.
player
.
save
();
}
public
Set
<
Integer
>
getUnlockedMaterial
()
{
return
unlockedMaterial
;
}
public
Set
<
Integer
>
getUnlockedBook
()
{
return
unlockedBook
;
}
public
Set
<
Integer
>
getUnlockedTip
()
{
return
unlockedTip
;
}
public
Set
<
Integer
>
getUnlockedView
()
{
return
unlockedView
;
}
public
Set
<
Integer
>
getUnlockedReliquary
()
{
return
unlockedReliquary
;
}
public
Set
<
Integer
>
getUnlockedReliquarySuitCodex
()
{
return
unlockedReliquarySuitCodex
;
}
}
\ No newline at end of file
src/main/java/emu/grasscutter/game/world/Scene.java
View file @
c2e620bf
...
...
@@ -312,10 +312,10 @@ public class Scene {
if
(
attacker
instanceof
EntityClientGadget
gadgetAttacker
)
{
var
clientGadgetOwner
=
getEntityById
(
gadgetAttacker
.
getOwnerEntityId
());
if
(
clientGadgetOwner
instanceof
EntityAvatar
)
{
((
EntityClientGadget
)
attacker
).
getOwner
().
getCodex
().
checkAnimal
(
target
,
CodexAnimalData
.
Co
dexAnimalUnlockCondition
.
CODEX_COUNT_TYPE_KILL
);
((
EntityClientGadget
)
attacker
).
getOwner
().
getCodex
().
checkAnimal
(
target
,
CodexAnimalData
.
Co
untType
.
CODEX_COUNT_TYPE_KILL
);
}
}
else
if
(
attacker
instanceof
EntityAvatar
avatarAttacker
)
{
avatarAttacker
.
getPlayer
().
getCodex
().
checkAnimal
(
target
,
CodexAnimalData
.
Co
dexAnimalUnlockCondition
.
CODEX_COUNT_TYPE_KILL
);
avatarAttacker
.
getPlayer
().
getCodex
().
checkAnimal
(
target
,
CodexAnimalData
.
Co
untType
.
CODEX_COUNT_TYPE_KILL
);
}
}
...
...
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