Fix online retrival of files with spaces. Implement built-in memory
reader for Touhou Mother module.
3
.settings/org.eclipse.core.resources.prefs
Normal file
@ -0,0 +1,3 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding//src/sig/modules/RabiRace/SessionCreateWindow.java=UTF-8
|
||||
encoding//src/sig/modules/RabiRace/SessionListWindow.java=UTF-8
|
BIN
Boss Sprites/Cirno.png
Normal file
After ![]() (image error) Size: 1.8 KiB |
BIN
Boss Sprites/DevilMachine.png
Normal file
After ![]() (image error) Size: 6.1 KiB |
BIN
Boss Sprites/ENEMYDiamondMasahirorin.png
Normal file
After ![]() (image error) Size: 2.6 KiB |
BIN
Boss Sprites/Masked_Maid_Girl.png
Normal file
After ![]() (image error) Size: 1.7 KiB |
BIN
Boss Sprites/Starman_Junior.png
Normal file
After ![]() (image error) Size: 1.2 KiB |
BIN
Boss Sprites/TME_-100.png
Normal file
After ![]() (image error) Size: 2.0 KiB |
BIN
Boss Sprites/TME_-10000.png
Normal file
After ![]() (image error) Size: 3.1 KiB |
BIN
Boss Sprites/TME_-101.png
Normal file
After ![]() (image error) Size: 1.5 KiB |
BIN
Boss Sprites/TME_-84.png
Normal file
After ![]() (image error) Size: 1.7 KiB |
BIN
Boss Sprites/TME_103.png
Normal file
After ![]() (image error) Size: 1.3 KiB |
BIN
Boss Sprites/TME_104.png
Normal file
After ![]() (image error) Size: 1.6 KiB |
BIN
Boss Sprites/TME_108.png
Normal file
After ![]() (image error) Size: 1.4 KiB |
BIN
Boss Sprites/TME_120.png
Normal file
After ![]() (image error) Size: 3.0 KiB |
BIN
Boss Sprites/TME_122.png
Normal file
After ![]() (image error) Size: 1.6 KiB |
BIN
Boss Sprites/TME_136.png
Normal file
After ![]() (image error) Size: 1.7 KiB |
BIN
Boss Sprites/TME_137.png
Normal file
After ![]() (image error) Size: 2.0 KiB |
BIN
Boss Sprites/TME_138.png
Normal file
After ![]() (image error) Size: 1.9 KiB |
BIN
Boss Sprites/TME_15.png
Normal file
After ![]() (image error) Size: 1.5 KiB |
BIN
Boss Sprites/TME_200.png
Normal file
After ![]() (image error) Size: 2.2 KiB |
BIN
Boss Sprites/TME_202.png
Normal file
After ![]() (image error) Size: 1.8 KiB |
BIN
Boss Sprites/TME_203.png
Normal file
After ![]() (image error) Size: 2.1 KiB |
BIN
Boss Sprites/TME_23.png
Normal file
After ![]() (image error) Size: 1.5 KiB |
BIN
Boss Sprites/TME_24.png
Normal file
After ![]() (image error) Size: 1.5 KiB |
BIN
Boss Sprites/TME_33.png
Normal file
After ![]() (image error) Size: 1.4 KiB |
BIN
Boss Sprites/TME_38.png
Normal file
After ![]() (image error) Size: 1.6 KiB |
BIN
Boss Sprites/TME_43.png
Normal file
After ![]() (image error) Size: 1.1 KiB |
BIN
Boss Sprites/TME_44.png
Normal file
After ![]() (image error) Size: 1.0 KiB |
BIN
Boss Sprites/TME_48.png
Normal file
After ![]() (image error) Size: 2.6 KiB |
BIN
Boss Sprites/TME_53.png
Normal file
After ![]() (image error) Size: 1.9 KiB |
BIN
Boss Sprites/TME_55.png
Normal file
After ![]() (image error) Size: 3.6 KiB |
BIN
Boss Sprites/TME_63.png
Normal file
After ![]() (image error) Size: 1.8 KiB |
BIN
Boss Sprites/TME_68.png
Normal file
After ![]() (image error) Size: 1.9 KiB |
BIN
Boss Sprites/TME_73.png
Normal file
After ![]() (image error) Size: 2.6 KiB |
BIN
Boss Sprites/TME_74.png
Normal file
After ![]() (image error) Size: 1.8 KiB |
BIN
Boss Sprites/TME_83.png
Normal file
After ![]() (image error) Size: 1.5 KiB |
BIN
Boss Sprites/TME_900000.png
Normal file
After ![]() (image error) Size: 1.2 KiB |
BIN
Boss Sprites/TME_999997.png
Normal file
After ![]() (image error) Size: 1.4 KiB |
BIN
Boss Sprites/TME_999999.png
Normal file
After ![]() (image error) Size: 2.5 KiB |
BIN
Boss Sprites/Youmu_Never_Loses.png
Normal file
After ![]() (image error) Size: 1.7 KiB |
0
sessions
Normal file
BIN
sigIRCv2.jar
@ -46,7 +46,7 @@ public class FileManager {
|
||||
if (!file.exists()) {
|
||||
System.out.println("Could not find "+file.getAbsolutePath()+", retrieving file online from "+serverURL+file.getName()+".");
|
||||
try {
|
||||
org.apache.commons.io.FileUtils.copyURLToFile(new URL(serverURL+fileloc),file);
|
||||
org.apache.commons.io.FileUtils.copyURLToFile(new URL(serverURL.replaceAll(" ", "%20")+fileloc.replaceAll(" ", "%20")),file);
|
||||
if (file.exists()) {
|
||||
System.out.println(" >> Successfully downloaded "+file.getAbsolutePath()+".");
|
||||
}
|
||||
|
@ -15,12 +15,24 @@ import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.Timer;
|
||||
|
||||
import com.sun.jna.Memory;
|
||||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.platform.win32.Kernel32;
|
||||
import com.sun.jna.platform.win32.WinNT;
|
||||
import com.sun.jna.platform.win32.WinNT.HANDLE;
|
||||
|
||||
import sig.FileManager;
|
||||
import sig.Module;
|
||||
import sig.sigIRC;
|
||||
import sig.modules.RabiRibi.MemoryOffset;
|
||||
import sig.modules.RabiRibi.MemoryType;
|
||||
import sig.modules.TouhouMother.DataProperty;
|
||||
import sig.modules.TouhouMother.IncreaseTouhouMotherClockCount;
|
||||
import sig.modules.TouhouMother.KillButton;
|
||||
@ -31,6 +43,7 @@ import sig.modules.TouhouMother.TouhouMotherButton;
|
||||
import sig.modules.TouhouMother.TouhouMotherCharacterData;
|
||||
import sig.modules.TouhouMother.TouhouPlayerCharacter;
|
||||
import sig.modules.TouhouMother.UpdateButton;
|
||||
import sig.modules.utils.PsapiTools;
|
||||
import sig.modules.utils.SemiValidInteger;
|
||||
import sig.modules.utils.SemiValidString;
|
||||
import sig.utils.DrawUtils;
|
||||
@ -51,6 +64,11 @@ public class TouhouMotherModule extends Module implements ActionListener{
|
||||
String real_gameData=SemiValidString.ERROR_VALUE;
|
||||
TouhouMotherBossData[] monsterDatabase;
|
||||
TouhouMotherCharacterData[] characterDatabase = new TouhouMotherCharacterData[4];
|
||||
final int PROCESS_PERMISSIONS = WinNT.PROCESS_QUERY_INFORMATION | WinNT.PROCESS_VM_READ;
|
||||
boolean foundTouhouMother = false;
|
||||
int touhouMotherPID = -1;
|
||||
long touhouMotherMemOffset = 0;
|
||||
public HANDLE touhouMotherProcess = null;
|
||||
|
||||
public List<TimeRecord> recordDatabase = new ArrayList<TimeRecord>();
|
||||
|
||||
@ -89,12 +107,92 @@ public class TouhouMotherModule extends Module implements ActionListener{
|
||||
DisableTouhouMotherClockCount();
|
||||
PopulateRecordDatabase();
|
||||
DefineButton();
|
||||
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
|
||||
CheckTouhouMotherClient();
|
||||
scheduler.scheduleWithFixedDelay(()->{
|
||||
CheckTouhouMotherClient();
|
||||
}, 5000, 5000, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
private void CheckTouhouMotherClient() {
|
||||
List<Integer> pids;
|
||||
try {
|
||||
pids = PsapiTools.getInstance().enumProcesses();
|
||||
boolean found=false;
|
||||
for (Integer pid : pids) {
|
||||
HANDLE process = Kernel32.INSTANCE.OpenProcess(PROCESS_PERMISSIONS, true, pid);
|
||||
List<sig.modules.utils.Module> hModules;
|
||||
try {
|
||||
hModules = PsapiTools.getInstance().EnumProcessModules(process);
|
||||
for(sig.modules.utils.Module m: hModules){
|
||||
/*if (m.getFileName().contains("rpg") || m.getFileName().contains("Touhou")) {
|
||||
System.out.println(m.getFileName()+":"+m.getEntryPoint());
|
||||
}*/
|
||||
if (m.getFileName().contains("RPG_RT")) {
|
||||
found=true;
|
||||
if (!foundTouhouMother) {
|
||||
touhouMotherMemOffset = Pointer.nativeValue(m.getLpBaseOfDll().getPointer());
|
||||
System.out.println("Found an instance of Touhou Mother at 0x"+Long.toHexString(touhouMotherMemOffset)+" | File:"+m.getFileName()+","+m.getBaseName());
|
||||
touhouMotherPID=pid;
|
||||
foundTouhouMother=true;
|
||||
touhouMotherProcess=process;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (process!=null) {
|
||||
Kernel32.INSTANCE.CloseHandle(process);
|
||||
}
|
||||
}
|
||||
if (!found && foundTouhouMother) {
|
||||
foundTouhouMother=false;
|
||||
System.out.println("Touhou Mother process lost.");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent ev) {
|
||||
memory = FileUtils.readFromFile(sigIRC.BASEDIR+"memory");
|
||||
//memory = FileUtils.readFromFile(sigIRC.BASEDIR+"memory");
|
||||
//System.out.println(Arrays.toString(memory));
|
||||
memory = new String[19];
|
||||
|
||||
memory[0] = Integer.toString(ReadIntFromBuriedMemoryOffset(0xA2A84,0x6DC,0x2C0,0x8,0x6AC,0x2F0));
|
||||
memory[1] = Integer.toString(ReadIntFromBuriedMemoryOffset(0xA2A90,0x8,0x2E8,0x8,0x6AC,0x2F0));
|
||||
memory[2] = Integer.toString(ReadIntFromBuriedMemoryOffset(0xA2A88,0x454,0x310,0x8,0x6AC,0x2F0));
|
||||
memory[3] = Integer.toString(ReadIntFromBuriedMemoryOffset(0xA2A68,0x3B4,0x37C,0x8,0x6AC,0x2F0));
|
||||
memory[4] = Integer.toString(ReadIntFromBuriedMemoryOffset(0xA2A88,0x6C,0x400,0x8,0x6AC,0x2F0));
|
||||
memory[5] = Integer.toString(ReadIntFromBuriedMemoryOffset(0xA2BA0,0x2B0,0x384,0x724,0x4D8,0x2DC));
|
||||
memory[6] = Integer.toString(ReadIntFromBuriedMemoryOffset(0xA2BA0,0x584,0x308,0x6C0,0x73C,0x2D0));
|
||||
memory[7] = Integer.toString(ReadIntFromBuriedMemoryOffset(0xA2A90,0x40,0x5C,0x34,0x6D8,0x190));
|
||||
memory[8] = Integer.toString(ReadIntFromBuriedMemoryOffset(0xA2A58,0x410,0x734,0x424,0x6DC,0x2F0));
|
||||
memory[9] = ReadStringFromBuriedMemoryOffset(0xA2BD8,0x68,0xC,0x0,0x0);
|
||||
memory[10] = ReadStringFromBuriedMemoryOffset(0xA2BD4,0x4,0x9C,0xC,0x0,0x0);
|
||||
memory[11] = ReadStringFromBuriedMemoryOffset(0xA2B70,0x1F8,0x278,0xC,0x0,0x0);
|
||||
memory[12] = ReadStringFromBuriedMemoryOffset(0xA2BD8,0x64,0x10,0x690,0x0,0x0);
|
||||
memory[13] = ReadStringFromBuriedMemoryOffset(0xA2BD8,0x10,0x694,0x690,0x0,0x0);
|
||||
memory[14] = Integer.toString(ReadIntFromBuriedMemoryOffset(0xA2BA0,0x654,0x308,0x4D4,0x720,0x140));
|
||||
memory[15] = Integer.toString(ReadIntFromBuriedMemoryOffset(0xA2BA0,0x27C,0x6FC,0x4D4,0x720,0x140));
|
||||
memory[16] = Integer.toString(ReadIntFromBuriedMemoryOffset(0xA2A58,0x144,0x728,0x5C,0x744,0x140));
|
||||
memory[17] = Integer.toString(ReadIntFromBuriedMemoryOffset(0xA2BA0,0x1F4,0x774,0x72C,0x4F4,0x140));
|
||||
memory[18] = Integer.toString(ReadIntFromBuriedMemoryOffset(0xA2A80,0x44,0x5F0,0x2A8,0x3EC,0x2A0));
|
||||
|
||||
/*System.out.println("Value 1: "+readIntFromMemory(0xA2BD8));
|
||||
System.out.println("Value 2: "+readIntFromMemoryOffset(0x64,readIntFromMemory(0xA2BD8)));
|
||||
System.out.println("Value 3: "+readIntFromMemoryOffset(0x10,readIntFromMemoryOffset(0x64,readIntFromMemory(0xA2BD8))));
|
||||
System.out.println("Value 4: "+readIntFromMemoryOffset(0x690,readIntFromMemoryOffset(0x10,readIntFromMemoryOffset(0x64,readIntFromMemory(0xA2BD8)))));
|
||||
System.out.println("Value 5: "+readIntFromMemoryOffset(0x0,readIntFromMemoryOffset(0x690,readIntFromMemoryOffset(0x10,readIntFromMemoryOffset(0x64,readIntFromMemory(0xA2BD8))))));
|
||||
System.out.println("Value 6: "+readStringFromMemoryOffset(0x0,readIntFromMemoryOffset(0x0,readIntFromMemoryOffset(0x690,readIntFromMemoryOffset(0x10,readIntFromMemoryOffset(0x64,readIntFromMemory(0xA2BD8)))))));*/
|
||||
|
||||
if (memory.length>=14) {
|
||||
ProcessMemoryData();
|
||||
ValidateAndControlMonsterData();
|
||||
@ -109,6 +207,35 @@ public class TouhouMotherModule extends Module implements ActionListener{
|
||||
killButton.run();
|
||||
}
|
||||
|
||||
public int ReadIntFromBuriedMemoryOffset(long...offsets) {
|
||||
int prev_val = 0;
|
||||
for (int i=0;i<offsets.length;i++) {
|
||||
if (i==0) {
|
||||
prev_val = readIntFromMemory(offsets[i]);
|
||||
} else {
|
||||
prev_val = readIntFromMemoryOffset(offsets[i],prev_val);
|
||||
}
|
||||
}
|
||||
return prev_val;
|
||||
}
|
||||
|
||||
public String ReadStringFromBuriedMemoryOffset(long...offsets) {
|
||||
int prev_val = 0;
|
||||
String final_val = "";
|
||||
for (int i=0;i<offsets.length;i++) {
|
||||
if (i==0) {
|
||||
prev_val = readIntFromMemory(offsets[i]);
|
||||
} else {
|
||||
if (i==offsets.length-1) {
|
||||
final_val = readStringFromMemoryOffset(offsets[i],prev_val);
|
||||
} else {
|
||||
prev_val = readIntFromMemoryOffset(offsets[i],prev_val);
|
||||
}
|
||||
}
|
||||
}
|
||||
return final_val;
|
||||
}
|
||||
|
||||
|
||||
public void run() {
|
||||
EnableAndDisableTimer();
|
||||
@ -266,7 +393,7 @@ public class TouhouMotherModule extends Module implements ActionListener{
|
||||
if (GetBossData(bossID.getValidInteger())!=null) {
|
||||
bossHP = new SemiValidInteger(Arrays.copyOfRange(memory, 0, 8),GetBossData(bossID.getValidInteger()).getHP(),currentBoss!=null,(bossHP!=null)?bossHP.getTrustedSlot():-1);
|
||||
gameData = new SemiValidString(Arrays.copyOfRange(memory, 9, 13));
|
||||
//System.out.println(bossHP.toString()+";"+bossID.toString()+";"+gameData.toString());
|
||||
System.out.println(bossHP.toString()+";"+bossID.toString()+";"+gameData.toString());
|
||||
real_bossHP = bossHP.getValidInteger();
|
||||
real_bossID = bossID.getValidInteger();
|
||||
real_gameData = gameData.getValidString();
|
||||
@ -465,6 +592,10 @@ public class TouhouMotherModule extends Module implements ActionListener{
|
||||
monsterdata.add(new TouhouMotherBossData("Miss Satori", 108, 900000, "TME_108.png"));
|
||||
monsterdata.add(new TouhouMotherBossData("Only God", 48, 4010, "TME_48.png"));
|
||||
monsterDatabase = monsterdata.toArray(new TouhouMotherBossData[monsterdata.size()]);
|
||||
FileManager manager;
|
||||
for (TouhouMotherBossData boss : monsterDatabase) {
|
||||
manager = new FileManager("Boss Sprites/"+boss.getImage()); manager.verifyAndFetchFileFromServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -522,4 +653,81 @@ public class TouhouMotherModule extends Module implements ActionListener{
|
||||
public Rectangle2D getBounds() {
|
||||
return position;
|
||||
}
|
||||
|
||||
|
||||
public int readIntFromMemory(long offset) {
|
||||
Memory mem = new Memory(4);
|
||||
Kernel32.INSTANCE.ReadProcessMemory(touhouMotherProcess, new Pointer(touhouMotherMemOffset+offset), mem, 4, null);
|
||||
return mem.getInt(0);
|
||||
}
|
||||
|
||||
public float readFloatFromMemory(long offset) {
|
||||
Memory mem = new Memory(4);
|
||||
Kernel32.INSTANCE.ReadProcessMemory(touhouMotherProcess, new Pointer(touhouMotherMemOffset+offset), mem, 4, null);
|
||||
return mem.getFloat(0);
|
||||
}
|
||||
|
||||
public float readFloatFromMemoryOffset(long val, long pointer) {
|
||||
Memory mem = new Memory(4);
|
||||
Kernel32.INSTANCE.ReadProcessMemory(touhouMotherProcess, new Pointer(pointer+val), mem, 4, null);
|
||||
return mem.getFloat(0);
|
||||
}
|
||||
|
||||
public int readIntFromMemoryOffset(long val, long pointer) {
|
||||
Memory mem = new Memory(4);
|
||||
Kernel32.INSTANCE.ReadProcessMemory(touhouMotherProcess, new Pointer(pointer+val), mem, 4, null);
|
||||
return mem.getInt(0);
|
||||
}
|
||||
|
||||
public String readStringFromMemoryOffset(long val, long pointer) {
|
||||
Memory mem = new Memory(128);
|
||||
Kernel32.INSTANCE.ReadProcessMemory(touhouMotherProcess, new Pointer(pointer+val), mem, 128, null);
|
||||
return mem.getString(0);
|
||||
}
|
||||
|
||||
public float readDirectFloatFromMemoryLocation(long pointer) {
|
||||
Memory mem = new Memory(4);
|
||||
Kernel32.INSTANCE.ReadProcessMemory(touhouMotherProcess, new Pointer(pointer), mem, 4, null);
|
||||
return mem.getFloat(0);
|
||||
}
|
||||
|
||||
public int readDirectIntFromMemoryLocation(long pointer) {
|
||||
Memory mem = new Memory(4);
|
||||
Kernel32.INSTANCE.ReadProcessMemory(touhouMotherProcess, new Pointer(pointer), mem, 4, null);
|
||||
return mem.getInt(0);
|
||||
}
|
||||
|
||||
public int readIntFromPointer(long val, long pointer) {
|
||||
Memory mem = new Memory(4);
|
||||
Kernel32.INSTANCE.ReadProcessMemory(touhouMotherProcess, new Pointer(readIntFromMemory(pointer)+val), mem, 4, null);
|
||||
return mem.getInt(0);
|
||||
}
|
||||
|
||||
public float readFloatFromPointer(long val, long pointer) {
|
||||
Memory mem = new Memory(4);
|
||||
Kernel32.INSTANCE.ReadProcessMemory(touhouMotherProcess, new Pointer(readIntFromMemory(pointer)+val), mem, 4, null);
|
||||
return mem.getFloat(0);
|
||||
}
|
||||
|
||||
public int readIntFromMemory(MemoryOffset val) {
|
||||
return (int)readFromMemory(val,MemoryType.INTEGER);
|
||||
}
|
||||
|
||||
public float readFloatFromMemory(MemoryOffset val) {
|
||||
return (float)readFromMemory(val,MemoryType.FLOAT);
|
||||
}
|
||||
|
||||
Object readFromMemory(MemoryOffset val, MemoryType type) {
|
||||
Memory mem = new Memory(type.getSize());
|
||||
Kernel32.INSTANCE.ReadProcessMemory(touhouMotherProcess, new Pointer(touhouMotherMemOffset+val.getOffset()), mem, type.getSize(), null);
|
||||
switch (type) {
|
||||
case FLOAT:
|
||||
return mem.getFloat(0);
|
||||
case INTEGER:
|
||||
return mem.getInt(0);
|
||||
default:
|
||||
System.out.println("WARNING! Type "+type+" does not have a defined value.");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -299,6 +299,7 @@ public class sigIRC{
|
||||
manager = new FileManager("sigIRC/rabi-ribi/unknown.png"); manager.verifyAndFetchFileFromServer();
|
||||
manager = new FileManager("sigIRC/rabi-ribi/characters",true); manager.verifyAndFetchFileFromServer();
|
||||
manager = new FileManager("sigIRC/rabi-ribi/items",true); manager.verifyAndFetchFileFromServer();
|
||||
manager = new FileManager("Boss Sprites/",true); manager.verifyAndFetchFileFromServer();
|
||||
//manager = new FileManager("sigIRC/sounds/Glaceon_cry.wav"); manager.verifyAndFetchFileFromServer();
|
||||
File follower_sounds_folder = new File(BASEDIR+"sigIRC/follower_sounds");
|
||||
if (!follower_sounds_folder.exists()) {
|
||||
|
1
tmp
Normal file
@ -0,0 +1 @@
|
||||
0
|
86
tmp_profile
Normal file
@ -0,0 +1,86 @@
|
||||
SigoNitori
|
||||
25
|
||||
8468886
|
||||
41
|
||||
41
|
||||
31
|
||||
25
|
||||
37
|
||||
60
|
||||
false
|
||||
5
|
||||
4
|
||||
100.0
|
||||
95.51538
|
||||
1527990500
|
||||
KEYITEMS:
|
||||
HAMMER;3
|
||||
CARROT_BOMB;3
|
||||
RIBBON;1
|
||||
SPEED_BOOST;3
|
||||
AUTO_EARRINGS;3
|
||||
RABI_SLIPPERS;1
|
||||
SUNNY_BEAM;1
|
||||
AIR_JUMP;1
|
||||
SLIDING_POWDER;3
|
||||
HOURGLASS;1
|
||||
BUNNY_WHIRL;3
|
||||
QUICK_BARRETTE;1
|
||||
HAMMER_WAVE;3
|
||||
HAMMER_ROLL;3
|
||||
LIGHT_ORB;3
|
||||
PLUS_NECKLACE;3
|
||||
EXPLODE_SHOT;1
|
||||
AIR_DASH;3
|
||||
BUNNY_STRIKE;3
|
||||
WALL_JUMP;3
|
||||
SPIKE_BARRIER;3
|
||||
BUNNY_AMULET;4
|
||||
SOUL_HEART;1
|
||||
BOOK_OF_CARROT;1
|
||||
CHAOS_ROD;1
|
||||
WATER_ORB;3
|
||||
FIRE_ORB;3
|
||||
NATURE_ORB;3
|
||||
P_HAIRPIN;3
|
||||
CYBER_FLOWER;1
|
||||
HEALING_STAFF;1
|
||||
MAX_BRACELET;1
|
||||
STRANGE_BOX;1
|
||||
CHARGE_RING;3
|
||||
CARROT_SHOOTER;1
|
||||
SUPER_CARROT;3
|
||||
BUNNY_CLOVER;1
|
||||
BADGES:
|
||||
BADGE_HEALTH_PLUS;2
|
||||
BADGE_TOXIC_STRIKE;2
|
||||
BADGE_DEF_GROW;1
|
||||
BADGE_MANA_SURGE;2
|
||||
BADGE_DEF_TRADE;1
|
||||
BADGE_ARMORED;1
|
||||
BADGE_CASHBACK;1
|
||||
BADGE_SURVIVAL;2
|
||||
BADGE_HEALTH_SURGE;2
|
||||
BADGE_MANA_PLUS;2
|
||||
BADGE_CRISIS_BOOST;2
|
||||
BADGE_ATK_GROW;1
|
||||
BADGE_ATK_TRADE;2
|
||||
BADGE_ARM_STRENGTH;2
|
||||
BADGE_CARROT_BOOST;1
|
||||
BADGE_WEAKEN;1
|
||||
BADGE_SELF_DEFENSE;1
|
||||
BADGE_LUCKY_SEVEN;2
|
||||
BADGE_HEX_CANCEL;1
|
||||
BADGE_PURE_LOVE;2
|
||||
BADGE_FRAME_CANCEL;2
|
||||
BADGE_HEALTH_WAGER;2
|
||||
BADGE_MANA_WAGER;1
|
||||
BADGE_STAMINA_PLUS;2
|
||||
BADGE_BLESSED;2
|
||||
BADGE_HITBOX_DOWN;2
|
||||
BADGE_TOP_FORM;2
|
||||
BADGE_TOUGH_SKIN;2
|
||||
BADGE_ERINA_BADGE;2
|
||||
BADGE_RIBBON_BADGE;2
|
||||
BADGE_AUTO_TRIGGER;1
|
||||
UPDATES:
|