Shared Item Detection [Not Working]
#1
Shared Item Detection

The code works, however, it bares the risk of reporting a false positive  for an unknown reason. I do not have the time to fix this bug. So, I will leave the code public for anyone who would like to try to fix it, or base a code off it.

This code will detect when a player tries to obtain a Shared Item, but the item they intend to cheat already has it's maximum amount in play. The code will also detect when a player obtains impossible item combinations. It will display the slot of the cheating player in the milliseconds of the timer, accompanied by a value denoting the reason.

(NTSC-U)
C26593FC 00000006
9421FFB0 BDC10008
907C0008 3EE080A1
62F70024 3F008053
631810A0 92F80000
B9C10008 38210050
60000000 00000000
C265EE14 00000008
9421FFB0 BDC10008
1D960004 3D8C8168
88030001 8A430003
2C120000 41A20014
2C120001 41820010
2C120002 40A00004
980C0193 B9C10008
38210050 00000000
C265EE30 00000058
9421FFB0 BDC10008
1D960004 3D8C8168
88100011 8A500013
2C120000 41A20014
2C120001 41820014
2C120002 40A00004
980C0193 4800027C
3DC08168 61CE0133
3DE08168 61EF0193
8A300012 7E8902A6
3EE038A0 3F008053
631810A0 2C110010
41820018 2C110011
41820010 2C110012
41820008 4800001C
2C000010 4182020C
2C000011 41820204
2C000012 418201FC
3A60000C 7E6903A6
8AAF0000 2C150006
40A20014 8AAE0000
3AB50001 9AAE0000
480000D8 2C150007
40A20014 8AAE0004
3AB50001 9AAE0004
480000C0 2C150008
40A20014 8AAE0008
3AB50001 9AAE0008
480000A8 2C150009
40A20014 8AAE000C
3AB50001 9AAE000C
48000090 2C15000A
40A20014 8AAE0010
3AB50001 9AAE0010
48000078 2C15000B
40A20014 8AAE0014
3AB50001 9AAE0014
48000060 2C15000C
40A20014 8AAE0018
3AB50001 9AAE0018
48000048 2C15000D
40820014 8AAE001C
3AB50001 9AAE001C
48000030 2C15000E
40A20014 8AAE0020
3AB50001 9AAE0020
48000018 2C15000F
40A20010 8AAE0024
3AB50001 9AAE0024
39EF0004 4200FF0C
2C000006 40A20014
8AAE0000 2C150003
408000E0 480000F0
2C000007 40A20014
8AAE0004 2C150001
408000C8 480000D8
2C000008 40A20014
8AAE0008 2C150001
408000B0 480000C0
2C000009 40A20014
8AAE000C 2C150003
40800098 480000A8
2C00000A 40A20014
8AAE0010 2C150002
40800080 48000090
2C00000B 40A20014
8AAE0014 2C150002
40800068 48000078
2C00000C 40A20014
8AAE0018 2C150001
40800050 48000060
2C00000D 40A20014
8AAE001C 2C150001
40800038 48000048
2C00000E 40A20014
8AAE0020 2C150001
40800020 48000030
2C00000F 40A20010
8AAE0024 2C150001
40800008 48000018
62F70064 48000008
62F7012C 7EF7B214
92F80000 3A60000A
7E6903A6 3EA00000
9AAE0000 39CE0004
4200FFF4 7E8903A6
B9C10008 38210050
60000000 00000000

(PAL)
C2661338 00000006
9421FFB0 BDC10008
907C0008 3EE080A1
62F70024 3F008053
63185BE8 92F80000
B9C10008 38210050
60000000 00000000
C265E18C 00000008
9421FFB0 BDC10008
1D960004 3D8C8168
88030001 8A430003
2C120000 41A20014
2C120001 41820010
2C120002 40A00004
980C0193 B9C10008
38210050 00000000
C265E1A8 00000058
9421FFB0 BDC10008
1D960004 3D8C8168
88100011 8A500013
2C120000 41A20014
2C120001 41820014
2C120002 40A00004
980C0193 4800027C
3DC08168 61CE0133
3DE08168 61EF0193
8A300012 7E8902A6
3EE038A0 3F008053
63185BE8 2C110010
41820018 2C110011
41820010 2C110012
41820008 4800001C
2C000010 4182020C
2C000011 41820204
2C000012 418201FC
3A60000C 7E6903A6
8AAF0000 2C150006
40A20014 8AAE0000
3AB50001 9AAE0000
480000D8 2C150007
40A20014 8AAE0004
3AB50001 9AAE0004
480000C0 2C150008
40A20014 8AAE0008
3AB50001 9AAE0008
480000A8 2C150009
40A20014 8AAE000C
3AB50001 9AAE000C
48000090 2C15000A
40A20014 8AAE0010
3AB50001 9AAE0010
48000078 2C15000B
40A20014 8AAE0014
3AB50001 9AAE0014
48000060 2C15000C
40A20014 8AAE0018
3AB50001 9AAE0018
48000048 2C15000D
40820014 8AAE001C
3AB50001 9AAE001C
48000030 2C15000E
40A20014 8AAE0020
3AB50001 9AAE0020
48000018 2C15000F
40A20010 8AAE0024
3AB50001 9AAE0024
39EF0004 4200FF0C
2C000006 40A20014
8AAE0000 2C150003
408000E0 480000F0
2C000007 40A20014
8AAE0004 2C150001
408000C8 480000D8
2C000008 40A20014
8AAE0008 2C150001
408000B0 480000C0
2C000009 40A20014
8AAE000C 2C150003
40800098 480000A8
2C00000A 40A20014
8AAE0010 2C150002
40800080 48000090
2C00000B 40A20014
8AAE0014 2C150002
40800068 48000078
2C00000C 40A20014
8AAE0018 2C150001
40800050 48000060
2C00000D 40A20014
8AAE001C 2C150001
40800038 48000048
2C00000E 40A20014
8AAE0020 2C150001
40800020 48000030
2C00000F 40A20010
8AAE0024 2C150001
40800008 48000018
62F70064 48000008
62F7012C 7EF7B214
92F80000 3A60000A
7E6903A6 3EA00000
9AAE0000 39CE0004
4200FFF4 7E8903A6
B9C10008 38210050
60000000 00000000

(NTSC-J)
C26609A4 00000006
9421FFB0 BDC10008
907C0008 3EE080A1
62F70024 3F008053
63185568 92F80000
B9C10008 38210050
60000000 00000000
C265D7F8 00000008
9421FFB0 BDC10008
1D960004 3D8C8168
88030001 8A430003
2C120000 41A20014
2C120001 41820010
2C120002 40A00004
980C0193 B9C10008
38210050 00000000
C265D814 00000058
9421FFB0 BDC10008
1D960004 3D8C8168
88100011 8A500013
2C120000 41A20014
2C120001 41820014
2C120002 40A00004
980C0193 4800027C
3DC08168 61CE0133
3DE08168 61EF0193
8A300012 7E8902A6
3EE038A0 3F008053
63185568 2C110010
41820018 2C110011
41820010 2C110012
41820008 4800001C
2C000010 4182020C
2C000011 41820204
2C000012 418201FC
3A60000C 7E6903A6
8AAF0000 2C150006
40A20014 8AAE0000
3AB50001 9AAE0000
480000D8 2C150007
40A20014 8AAE0004
3AB50001 9AAE0004
480000C0 2C150008
40A20014 8AAE0008
3AB50001 9AAE0008
480000A8 2C150009
40A20014 8AAE000C
3AB50001 9AAE000C
48000090 2C15000A
40A20014 8AAE0010
3AB50001 9AAE0010
48000078 2C15000B
40A20014 8AAE0014
3AB50001 9AAE0014
48000060 2C15000C
40A20014 8AAE0018
3AB50001 9AAE0018
48000048 2C15000D
40820014 8AAE001C
3AB50001 9AAE001C
48000030 2C15000E
40A20014 8AAE0020
3AB50001 9AAE0020
48000018 2C15000F
40A20010 8AAE0024
3AB50001 9AAE0024
39EF0004 4200FF0C
2C000006 40A20014
8AAE0000 2C150003
408000E0 480000F0
2C000007 40A20014
8AAE0004 2C150001
408000C8 480000D8
2C000008 40A20014
8AAE0008 2C150001
408000B0 480000C0
2C000009 40A20014
8AAE000C 2C150003
40800098 480000A8
2C00000A 40A20014
8AAE0010 2C150002
40800080 48000090
2C00000B 40A20014
8AAE0014 2C150002
40800068 48000078
2C00000C 40A20014
8AAE0018 2C150001
40800050 48000060
2C00000D 40A20014
8AAE001C 2C150001
40800038 48000048
2C00000E 40A20014
8AAE0020 2C150001
40800020 48000030
2C00000F 40A20010
8AAE0024 2C150001
40800008 48000018
62F70064 48000008
62F7012C 7EF7B214
92F80000 3A60000A
7E6903A6 3EA00000
9AAE0000 39CE0004
4200FFF4 7E8903A6
B9C10008 38210050
60000000 00000000

(NTSC-K)
C264F650 00000006
9421FFB0 BDC10008
907C0008 3EE080A1
62F70024 3F008052
63183C40 92F80000
B9C10008 38210050
60000000 00000000
C264C4A4 00000008
9421FFB0 BDC10008
1D960004 3D8C8168
88030001 8A430003
2C120000 41A20014
2C120001 41820010
2C120002 40A00004
980C0193 B9C10008
38210050 00000000
C264C4C0 00000058
9421FFB0 BDC10008
1D960004 3D8C8168
88100011 8A500013
2C120000 41A20014
2C120001 41820014
2C120002 40A00004
980C0193 4800027C
3DC08168 61CE0133
3DE08168 61EF0193
8A300012 7E8902A6
3EE038A0 3F008052
63183C40 2C110010
41820018 2C110011
41820010 2C110012
41820008 4800001C
2C000010 4182020C
2C000011 41820204
2C000012 418201FC
3A60000C 7E6903A6
8AAF0000 2C150006
40A20014 8AAE0000
3AB50001 9AAE0000
480000D8 2C150007
40A20014 8AAE0004
3AB50001 9AAE0004
480000C0 2C150008
40A20014 8AAE0008
3AB50001 9AAE0008
480000A8 2C150009
40A20014 8AAE000C
3AB50001 9AAE000C
48000090 2C15000A
40A20014 8AAE0010
3AB50001 9AAE0010
48000078 2C15000B
40A20014 8AAE0014
3AB50001 9AAE0014
48000060 2C15000C
40A20014 8AAE0018
3AB50001 9AAE0018
48000048 2C15000D
40820014 8AAE001C
3AB50001 9AAE001C
48000030 2C15000E
40A20014 8AAE0020
3AB50001 9AAE0020
48000018 2C15000F
40A20010 8AAE0024
3AB50001 9AAE0024
39EF0004 4200FF0C
2C000006 40A20014
8AAE0000 2C150003
408000E0 480000F0
2C000007 40A20014
8AAE0004 2C150001
408000C8 480000D8
2C000008 40A20014
8AAE0008 2C150001
408000B0 480000C0
2C000009 40A20014
8AAE000C 2C150003
40800098 480000A8
2C00000A 40A20014
8AAE0010 2C150002
40800080 48000090
2C00000B 40A20014
8AAE0014 2C150002
40800068 48000078
2C00000C 40A20014
8AAE0018 2C150001
40800050 48000060
2C00000D 40A20014
8AAE001C 2C150001
40800038 48000048
2C00000E 40A20014
8AAE0020 2C150001
40800020 48000030
2C00000F 40A20010
8AAE0024 2C150001
40800008 48000018
62F70064 48000008
62F7012C 7EF7B214
92F80000 3A60000A
7E6903A6 3EA00000
9AAE0000 39CE0004
4200FFF4 7E8903A6
B9C10008 38210050
60000000 00000000



Code:
#============================================================#
#                    Source                            #
#============================================================#

#============================================================#
#                    Local SELECT Record                     #
#============================================================#
# Original Address Ports:                                    #
# RMCE - 0x806593FC                                          #
# RMCP - 0x80661338                                          #
# RMCJ - 0x806609A4                                          #
# RMCK - 0x8064F650                                          #
#============================================================#

.set millisecondsDisplayAddress, 0x0
.set region, ''

.if     (region == 'E' || region == 'e') # RMCE
    millisecondsDisplayAddress = 0x805310A0
.elseif (region == 'P' || region == 'p') # RMCP
    millisecondsDisplayAddress = 0x80535BE8
.elseif (region == 'J' || region == 'j') # RMCJ
    millisecondsDisplayAddress = 0x80535568
.elseif (region == 'K' || region == 'k') # RMCK
    millisecondsDisplayAddress = 0x80523C40
.else # Invalid Region
    .abort
.endif

#============================================================#
#              Registers & Offsets                     #
#------------------------------------------------------------#
# 8(r28) = NULL or time of sender                            #
#============================================================#
# r3  = NULL or time of sender                               #
# r23 = Milliseconds Display Modifier Deactivator            #
# r24 = Address to Milliseconds Display Modifier             #
# r28 = Address to SELECT Record                             #
#============================================================#

stwu r1, -80(r1) # Make space for 18 registers
stmw r14, 8(r1) # Push r14-r31 onto the stack

# Original instruction
stw r3, 8(r28) # Store in r3 (NULL or time of sender) at the address in r28 offset by 8

#============================================================#
#                 Purpose                              #
#------------------------------------------------------------#
# Reset the timer back to the default milliseconds after     #
# each race. If the timer was not changed, no harm done.     #
#                                                            #
# This instruction is only executed before a race starts,    #
# so the timer will always be reset for a new race.          #
#============================================================#

lis r23, 0x80A1 # Set the higher 16 bits of r23 (Milliseconds Display Modifier Deactivator) to 0x38A0
ori r23, r23, 0x0024 # Set the lower 16 bits of r23 (Milliseconds Display Modifier Deactivator) to 0x0024

lis r24, millisecondsDisplayAddress@ha # Set the higher 16 bits of r24 (Address to Milliseconds Display Modifier)
ori r24, r24, millisecondsDisplayAddress@l # Set the lower 16 bits of r24 (Address to Milliseconds Display Modifier)

stw r23, 0x0(r24) # Store the word in r23 (Milliseconds Display Modifier Deactivator) at the address in r24

lmw r14, 8(r1) # Pop r14-r31 off the stack
addi r1, r1, 80 # Release the space

~

#============================================================#
#                Local Player's ITEM Record                  #
#============================================================#
# Original Address Ports:                                    #
# RMCE - 0x8065EE14                                          #
# RMCP - 0x8065E18C                                          #
# RMCJ - 0x8065D7F8                                          #
# RMCK - 0x8064C4A4                                          #
#============================================================#

#============================================================#
#              Registers & Offsets                     #
#------------------------------------------------------------#
# 0(r3) = Start time of Local Client's item                  #
# 1(r3) = Local Client's Held Item                           #
# 2(r3) = Local Client's Trailed Item                        #
# 3(r3) = Local Client's Activation Mode                     #
#============================================================#
# r0  = Local Client's Held Item                             #
# r3  = Address to ITEM Record                               #
# r12 = Address to offset for original Item Spy              #
# r18 = Local Client's Activation Mode                       #
# r22 = Local Client's Slot                                  #
#============================================================#

stwu r1, -80(r1) # Make space for 18 registers
stmw r14, 8(r1)  # Push r14-r31 onto the stack

mulli r12, r22, 4 # Multiply the value in r22 (Local Player Slot) by 4 and place the lower 32 bits of the result in r12
subis r12, r12, 32408 # Subtract the value in r12 by 32408, then shift r12 16 bits to the left and store the result in r12

# Original instruction
lbz r0, 1(r3)  # Load the byte at the address in r3 offset by 1 (Local Player's Held Item) and store it in r0
lbz r18, 3(r3) # Load the byte at the address in r3 offset by 3 (Local Player's Activation Mode) and store it in r18

#============================================================#
#                 Purpose                              #
#------------------------------------------------------------#
# Find the current activation mode of the client.            #
#============================================================#

cmpwi r18, 0x0 # Compare the value in r18 (Local Player's Activation Mode) to 0x0
beq+ branch_handshake_stage_not_1 # Branch if equal
cmpwi r18, 0x1 # Compare the value in r18 (Local Player's Activation Mode) to 0x1
beq- branch_finished # Branch if equal
cmpwi r18, 0x2 # Compare the value in r18 (Local Player's Activation Mode) to 0x2
bge+ branch_handshake_stage_not_1 # Branch if greater or equal

#============================================================#
#                 Purpose                              #
#------------------------------------------------------------#
# Store the Client's Held Item to the Item Spy.              #
#                                                            #
# Activation Mode:                                           #
# 0 - No Item                                                #
# 2 - Item client will receive                               #
# 3 -                                                        #
# 4 - Ready to fire triple items                             #
# 5 -                                                        #
# 6 - Ready to fire single item                              #
# 7 - No Item Available                                      #
#============================================================#

branch_handshake_stage_not_1:

stb r0, 403(r12) # Store the byte in r0 (Player's Held Item) to the address in r12 offset by 403

#============================================================#
#                 Purpose                              #
#------------------------------------------------------------#
# To stay consistent with the other players, we do not store #
# the pending item at handshake stage 1.                     #
#                                                            #
# This code will not include Local Client detection,         #
# as the code length would be doubled for little purpose.    #
#                                                            #
# Handshake Value:                                           #
# 1 - Item client wants                                      #
#============================================================#

branch_finished:

lmw r14, 8(r1) # Pop r14-r31 off the stack
addi r1, r1, 80 # Release the space

~

#============================================================#
#                   Players ITEM Record                      #
#============================================================#
# Original Address Ports:                                    #
# RMCE - 0x8065EE30                                          #
# RMCP - 0x8065E1A8                                          #
# RMCJ - 0x8065D814                                          #
# RMCK - 0x8064C4C0                                          #
#============================================================#

.set millisecondsDisplayAddress, 0x0
.set region, ''

.if     (region == 'E' || region == 'e') # RMCE
    millisecondsDisplayAddress = 0x805310A0
.elseif (region == 'P' || region == 'p') # RMCP
    millisecondsDisplayAddress = 0x80535BE8
.elseif (region == 'J' || region == 'j') # RMCJ
    millisecondsDisplayAddress = 0x80535568
.elseif (region == 'K' || region == 'k') # RMCK
    millisecondsDisplayAddress = 0x80523C40
.else # Invalid Region
    .abort
.endif

#============================================================#
#              Registers & Offsets                     #
#------------------------------------------------------------#
# 16(r16) = Start time of item                               #
# 17(r16) = Held Item                                        #
# 18(r16) = Trailed Item                                     #
# 19(r16) = Activation Mode                                  #
#============================================================#
# r0  = Player's Held Item                                   #
# r12 = Address to offset for original Item Spy              #
# r14 = Address to number of Items in play                   #
# r15 = Address to all Player's Items                        #
# r16 = Address to ITEM Record                               #
# r17 = Player's Trailed Item                                #
# r18 = Player's Activation Mode                             #
# r19 = Count Register Loop Value                            #
# r20 = Preserved Count Register Loop Value                  #
# r21 = nth Player's Item / Number of n Item in play         #
# r22 = Player's Slot                                        #
# r23 = Milliseconds Display Modifier                        #
# r24 = Address to Milliseconds Display Modifier             #
#============================================================#

stwu r1, -80(r1) # Make space for 18 registers
stmw r14, 8(r1)  # Push r14-r31 onto the stack

mulli r12, r22, 4 # Multiply the value in r22 (Player Slot) by 4 and place the lower 32 bits of the result in r12
subis r12, r12, 32408 # Subtract the value in r12 by 32408, then shift r12 16 bits to the left and store the result in r12

# Original instruction
lbz r0, 17(r16)  # Load the byte at the address in r16 offset by 17 (Player's Held Item) and store it in r0
lbz r18, 19(r16) # Load the byte at the address in r16 offset by 19 (Player's Activation Mode) and store it in r18

#============================================================#
#                 Purpose                              #
#------------------------------------------------------------#
# Find the current activation mode of the player.            #
#============================================================#

cmpwi r18, 0x0 # Compare the value in r18 (Player's Activation Mode) to 0x0
beq+ branch_handshake_stage_not_1 # Branch if equal
cmpwi r18, 0x1 # Compare the value in r18 (Player's Activation Mode) to 0x1
beq- branch_handshake_stage_1 # Branch if equal
cmpwi r18, 0x2 # Compare the value in r18 (Player's Activation Mode) to 0x2
bge+ branch_handshake_stage_not_1 # Branch if greater than or equal

#============================================================#
#                 Purpose                              #
#------------------------------------------------------------#
# Store the Player's Held Item to Item Spy.                  #
#                                                            #
# Activation Mode:                                           #
# 0 - No Item                                                #
# 2 - Item player will receive                               #
# 3 -                                                        #
# 4 - Ready to fire triple items                             #
# 5 -                                                        #
# 6 - Ready to fire single item                              #
# 7 - No Item Available                                      #
#============================================================#

branch_handshake_stage_not_1:

stb r0, 403(r12) # Store the byte in r0 (Player's Held Item) to the address in r12 offset by 403

b branch_finished

#============================================================#
#                 Purpose                              #
#------------------------------------------------------------#
# Detect players trying to obtain impossible Shared Items    #
# using a variety of methods.                                #
#                                                            #
# Handshake Value:                                           #
# 1 - Item player wants                                      #
#============================================================#

branch_handshake_stage_1:

lis r14, 0x8168 # Set the higher 16 bits of r14 (Address to number of items in play) to 0x8168
ori r14, r14, 0x0133 # Set the lower 16 bits of r14 (Address to number of items in play) to 0x0133

lis r15, 0x8168 # Set the higher 16 bits of r15 (Address to all Player's Items) to 0x8168
ori r15, r15, 0x0193 # Set the lower 16 bits of r15 (Address to all Player's Items) to 0x0193

lbz r17, 18(r16) # Load the byte at the address in r16 offset by 18 (Player's Trailed Item) and store it in r17

mfctr r20 # Preserve the value in the Count Register in r20

lis r23, 0x38A0 # Set the higher 16 bits of r23 (Milliseconds Display Modifier) to 0x38A0

lis r24, millisecondsDisplayAddress@ha # Set the higher 16 bits of r24 (Address to Milliseconds Display Modifier)
ori r24, r24, millisecondsDisplayAddress@l # Set the lower 16 bits of r24 (Address to Milliseconds Display Modifier)

#============================================================#
#                 Purpose                              #
#------------------------------------------------------------#
# Check the if the current player has impossible             #
# items trailing them, according to their current            #
# item.                                                      #
#                                                            #
# It is impossible for a player to obtain another set of     #
# triple items if they are currently trailing a set.         #
#============================================================#

cmpwi r17, 0x10 # Compare the value in r17 (Player's Trailed Item) to 0x10 (Triple Green Shells)
beq- branch_impossible_trailed_items_check # Branch if equal
cmpwi r17, 0x11 # Compare the value in r17 (Player's Trailed Item) to 0x11 (Triple Red Shells)
beq- branch_impossible_trailed_items_check # Branch if equal
cmpwi r17, 0x12 # Compare the value in r17 (Player's Trailed Item) to 0x12 (Triple Bananas)
beq- branch_impossible_trailed_items_check # Branch if equal

b branch_skip_impossible_trailed_items_check

branch_impossible_trailed_items_check:
cmpwi r0, 0x10 # Compare the value in r0 (Player's Held Item) to 0x10 (Triple Green Shells)
beq- branch_impossible_triple_item_combination_detected # Branch if equal
cmpwi r0, 0x11 # Compare the value in r0 (Player's Held Item) to 0x11 (Triple Red Shells)
beq- branch_impossible_triple_item_combination_detected # Branch if equal
cmpwi r0, 0x12 # Compare the value in r0 (Player's Held Item) to 0x12 (Triple Bananas)
beq- branch_impossible_triple_item_combination_detected # Branch if equal

branch_skip_impossible_trailed_items_check:

#============================================================#
#                 Purpose                              #
#------------------------------------------------------------#
# Store the amount of each item currently in play,           #
# not including the player's pending item.                   #
#                                                            #
# * The player will be reporting a value of 0x14 as their    #
# current item. This is because they had nothing in their    #
# inventory before touching an item box.                     #
#                                                            #
# * If a player does not have any of these items, nothing    #
# will happen.                                               #
#                                                            #
# * If there are not 12 players in the room, the extra       #
# values will all be 0 and nothing will happen (This area of #
# memory automatically clears after each race).              #
#                                                            #
# * r15 gets trashed.                                        #
# * r19 gets trashed.                                        #
# * r21 gets trashed.                                        #
#============================================================#

li r19, 12 # Load 12 into r19 (Count Register Loop Amount)
mtctr r19 # Move r19 (Count Register Loop Amount) into the Count Register

branch_item_amount_loop:

lbz r21, 0(r15) # Load the byte at the address in r15 (nth Player's Item) and store it in r21

cmpwi r21, 0x6 # Compare the value in r21 (nth Player's Item) to 0x6 (Bob-omb)
bne+ branch_item_not_bob_omb # Branch if not equal
lbz r21, 0x0(r14) # Load the byte at the address in r14 (Number of Bob-ombs in play) and store it in r21
addi r21, r21, 0x1 # Add 0x1 to r21 (Number of Bob-ombs in play) and store the result in r21
stb r21, 0x0(r14) # Store the byte in r21 (Number of Bob-ombs in play) to the address in r14
b branch_item_found # Branch to check the next player since we found the item this player is holding
branch_item_not_bob_omb:

cmpwi r21, 0x7
bne+ branch_item_not_blue_shell
lbz r21, 0x4(r14)
addi r21, r21, 0x1
stb r21, 0x4(r14)
b branch_item_found
branch_item_not_blue_shell:

cmpwi r21, 0x8
bne+ branch_item_not_lightning
lbz r21, 0x8(r14)
addi r21, r21, 0x1
stb r21, 0x8(r14)
b branch_item_found
branch_item_not_lightning:

cmpwi r21, 0x9
bne+ branch_item_not_star
lbz r21, 0xC(r14)
addi r21, r21, 0x1
stb r21, 0xC(r14)
b branch_item_found
branch_item_not_star:

cmpwi r21, 0xA
bne+ branch_item_not_golden_mushroom
lbz r21, 0x10(r14)
addi r21, r21, 0x1
stb r21, 0x10(r14)
b branch_item_found
branch_item_not_golden_mushroom:

cmpwi r21, 0xB
bne+ branch_item_not_mega_mushroom
lbz r21, 0x14(r14)
addi r21, r21, 0x1
stb r21, 0x14(r14)
b branch_item_found
branch_item_not_mega_mushroom:

cmpwi r21, 0xC
bne+ branch_item_not_blooper
lbz r21, 0x18(r14)
addi r21, r21, 0x1
stb r21, 0x18(r14)
b branch_item_found
branch_item_not_blooper:

cmpwi r21, 0xD
bne- branch_item_not_pow_block
lbz r21, 0x1C(r14)
addi r21, r21, 0x1
stb r21, 0x1C(r14)
b branch_item_found
branch_item_not_pow_block:

cmpwi r21, 0xE
bne+ branch_item_not_thunder_cloud
lbz r21, 0x20(r14)
addi r21, r21, 0x1
stb r21, 0x20(r14)
b branch_item_found
branch_item_not_thunder_cloud:

cmpwi r21, 0xF
bne+ branch_item_not_bullet_bill
lbz r21, 0x24(r14)
addi r21, r21, 0x1
stb r21, 0x24(r14)
branch_item_not_bullet_bill:

branch_item_found:

addi r15, r15, 0x4 # Add 0x4 to r15 (Address to all Player's items) and store the result in r15
bdnz+ branch_item_amount_loop # Branch and decrement the Count Register while not zero

#============================================================#
#                 Purpose                              #
#------------------------------------------------------------#
# Now that we have the amount of each item in play,          #
# we can compare them to their hardcoded limits.             #
#                                                            #
# If the amount in play is equal (or greater) to the max,    #
# the current player must be trying to cheat one.            #
# This is because they are trying obtain one when the game   #
# would never allow it due to the hardcoded limits.          #
#                                                            #
# This is possible because for a brief period during         #
# phase 1 of the handshake, the player will report their     #
# held item as they one they would like to receive.          #
#                                                            #
# * If a player does not have any of these items, nothing    #
# will happen.                                               #
#                                                            #
# * This area of memory automatically clears after each race.#
#                                                            #
# * r21 gets trashed.                                        #
#============================================================#

cmpwi r0, 0x6 # Compare the value in r0 (Player's Held Item) to 0x6 (Bob-omb)
bne+ branch_not_checking_bob_omb_limit # Branch if not equal
lbz r21, 0x0(r14) # Load the byte at the address in r14 (Number of Bob-ombs in play) and store it in r21
cmpwi r21, 0x3 # Compare the value in r21 (Number of Bob-ombs in play) to 0x3 (Max Number of Bob-ombs)
bge- branch_impossible_shared_item_detected # Branch if greater than or equal
b branch_impossible_shared_item_not_detected # Branch since the item did not attempt to break any rules
branch_not_checking_bob_omb_limit:

cmpwi r0, 0x7
bne+ branch_not_checking_blue_shell_limit
lbz r21, 0x4(r14)
cmpwi r21, 0x1
bge- branch_impossible_shared_item_detected
b branch_impossible_shared_item_not_detected
branch_not_checking_blue_shell_limit:

cmpwi r0, 0x8
bne+ branch_not_checking_lightning_limit
lbz r21, 0x8(r14)
cmpwi r21, 0x1
bge- branch_impossible_shared_item_detected
b branch_impossible_shared_item_not_detected
branch_not_checking_lightning_limit:

cmpwi r0, 0x9
bne+ branch_not_checking_star_limit
lbz r21, 0xC(r14)
cmpwi r21, 0x3
bge- branch_impossible_shared_item_detected
b branch_impossible_shared_item_not_detected
branch_not_checking_star_limit:

cmpwi r0, 0xA
bne+ branch_not_checking_golden_mushroom_limit
lbz r21, 0x10(r14)
cmpwi r21, 0x2
bge- branch_impossible_shared_item_detected
b branch_impossible_shared_item_not_detected
branch_not_checking_golden_mushroom_limit:

cmpwi r0, 0xB
bne+ branch_not_checking_mega_mushroom_limit
lbz r21, 0x14(r14)
cmpwi r21, 0x2
bge- branch_impossible_shared_item_detected
b branch_impossible_shared_item_not_detected
branch_not_checking_mega_mushroom_limit:

cmpwi r0, 0xC
bne+ branch_not_checking_blooper_limit
lbz r21, 0x18(r14)
cmpwi r21, 0x1
bge- branch_impossible_shared_item_detected
b branch_impossible_shared_item_not_detected
branch_not_checking_blooper_limit:

cmpwi r0, 0xD
bne+ branch_not_checking_pow_block_limit
lbz r21, 0x1C(r14)
cmpwi r21, 0x1
bge- branch_impossible_shared_item_detected
b branch_impossible_shared_item_not_detected
branch_not_checking_pow_block_limit:

cmpwi r0, 0xE
bne+ branch_not_checking_thunder_cloud_limit
lbz r21, 0x20(r14)
cmpwi r21, 0x1
bge- branch_impossible_shared_item_detected
b branch_impossible_shared_item_not_detected
branch_not_checking_thunder_cloud_limit:

cmpwi r0, 0xF
bne+ branch_not_checking_bullet_bill_limit
lbz r21, 0x24(r14)
cmpwi r21, 0x1
bge- branch_impossible_shared_item_detected
branch_not_checking_bullet_bill_limit:

b branch_impossible_shared_item_not_detected

#============================================================#
#                 Purpose                              #
#------------------------------------------------------------#
# The first digit on the timer will denote the detection     #
# reason. The third digit will denote the player's slot in   #
# the room (0 - 11).                                         #
#                                                            #
# They are as follows:                                       #
# 10X - Impossible Shared Item Detected                      #
# 30X - Impossible Triple Item Combination Detected          #
#                                                            #
# * r23 gets trashed                                         #
#============================================================#

branch_impossible_shared_item_detected:

ori r23, r23, 0x0064 # Set the lower 16 bits of r23 (Milliseconds Display Modifier) to 0x0064 [100]

b branch_modify_timer

branch_impossible_triple_item_combination_detected:

ori r23, r23, 0x012C # Set the lower 16 bits of r23 (Milliseconds Display Modifier) to 0x012C [300]

branch_modify_timer:

add r23, r23, r22 # Add the value in r22 (Player's Slot) to the value in r23
stw r23, 0(r24) # Store the word in r23 (Milliseconds Display Modifier) to the address in r24

#============================================================#
#                 Purpose                              #
#------------------------------------------------------------#
# Erase the amount of items currently in play.               #
#                                                            #
# * r14 gets trashed.                                        #
# * r19 gets trashed.                                        #
# * r21 gets trashed.                                        #
#============================================================#

branch_impossible_shared_item_not_detected:

li r19, 10 # Load 10 into r19 (Count Register Loop Amount)
mtctr r19 # Move r19 (Count Register Loop Amount) into the Count Register

branch_clear_item_amount_loop:

lis r21, 0x0 # Set the higher 16 bits of r21 (nth Player's Item) to 0x0000 and clear the lower 16 bits
stb r21, 0x0(r14) # Store the byte in r21 (0x00) to the address in r14 (Number of n in play)

addi r14, r14, 0x4 # Add 0x4 to r14 and store the result in r14 (Number of n in play)

bdnz+ branch_clear_item_amount_loop # Branch and decrement the Count Register while not zero

mtctr r20 # Move the value in r20 (Preserved Count Register Loop Amount) into the Count Register

branch_finished:

lmw r14, 8(r1) # Pop r14-r31 off the stack
addi r1, r1, 80 # Release the space



Notes:
- If a detection occurs, the milliseconds will return to normal when the next race begins.
- This code relies on a specific value in the ITEM Packet, and it is very quick to change. Due to the nature of how often updates are sent to other clients when there are many players in the room, it is recommended to have all P2P connections set up (NATNEG complete).

Code Creator: Star
Code Credits: mdmwii (Item Warning), Bully@WiiPlaza (USB Gecko Item Spy, Millisecond Display Modifier)
Reply
#2
Hell yeah! Inb4 random noobs use it in laggy WW's and come back here saying the code doesn't work.
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)