Skip to content

Commit

Permalink
Fix identification of entity list in 20w30a
Browse files Browse the repository at this point in the history
Refactoring in that snapshot moved the disconnect.lost string constant in NHPC into a static initializer, which put it at the end of the constant list.  NHPC also has the Skipping Entity with id constant, which means that it ended up matching as the entity list instead (since that was now before disconnect.lost).  Then the actual entity list also matched, which threw an exception.

The fix is to make Skipping Entity with id a lower priority constant.
  • Loading branch information
Pokechu22 committed Nov 12, 2020
1 parent ffd0520 commit 7b528cd
Showing 1 changed file with 36 additions and 13 deletions.
49 changes: 36 additions & 13 deletions burger/toppings/identify.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
# We can identify almost every class we need just by
# looking for consistent strings.
MATCHES = (
(['Skipping Entity with id'], 'entity.list'),
(['Fetching addPacket for removed entity'], 'entity.trackerentry'),
(['#%04d/%d%s', 'attribute.modifier.equals.'], 'itemstack'),
(['disconnect.lost'], 'nethandler.client'),
Expand All @@ -55,13 +54,36 @@
((['HORIZONTAL'], True), 'enumfacing.plane')
)

# Enforce a lower priority on some matches, since some classes may match both
# these and other strings, which we want to be grouped with the other string
# if it exists, and with this if it doesn't
MAYBE_MATCHES = (
(['Skipping Entity with id'], 'entity.list'),
)

# In some cases there really isn't a good way to verify that it's a specific
# class and we need to just depend on it coming first (bad!)
# The biome class specifically is an issue because in 18w06a, the old name is
# present in the biome's own class, but the ID is still in the register class.
# This stops being an issue later into 1.13 when biome names become translatable.
IGNORE_DUPLICATES = [ "biome.register" ]

def check_match(value, match_list):
exact = False
if isinstance(match_list, tuple):
match_list, exact = match_list

for match in match_list:
if exact:
if value != match:
continue
else:
if match not in value:
continue

return True
return False

def identify(classloader, path, verbose):
"""
The first pass across the jar will identify all possible classes it
Expand All @@ -71,23 +93,21 @@ def identify(classloader, path, verbose):
check for known signatures and predictable constants. In the next pass,
we'll have the initial mapping from this pass available to us.
"""
possible_match = None

for c in classloader.search_constant_pool(path=path, type_=String):
value = c.string.value
for match_list, match_name in MATCHES:
exact = False
if isinstance(match_list, tuple):
match_list, exact = match_list

for match in match_list:
if exact:
if value != match:
continue
else:
if match not in value:
continue

if check_match(value, match_list):
class_file = classloader[path]
return match_name, class_file.this.name.value

for match_list, match_name in MAYBE_MATCHES:
if check_match(value, match_list):
class_file = classloader[path]
possible_match = (match_name, class_file.this.name.value)
# Continue searching through the other constants in the class

if 'BaseComponent' in value:
class_file = classloader[path]
# We want the interface for chat components, but it has no
Expand Down Expand Up @@ -224,6 +244,9 @@ def is_protected_final(m):
elif verbose:
print("Found ParticleArgument as %s, but it didn't implement the expected interface" % path)

# May (will usually) be None
return possible_match


class IdentifyTopping(Topping):
"""Finds important superclasses needed by other toppings."""
Expand Down

0 comments on commit 7b528cd

Please sign in to comment.