This repository has been archived by the owner on Aug 6, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 2d5fbe3
Showing
18 changed files
with
1,420 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
parsers | ||
__pycache__ | ||
Plugins/__pycache__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
[submodule "valorlib"] | ||
path = valorlib | ||
url = https://github.com/swrlly/valorlib.git |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
effect0 = { | ||
"Quiet" : 2, | ||
"Weak" : 4, | ||
"Slowed" : 8, | ||
"Sick" : 16, | ||
"Dazed" : 32, | ||
"Stunned" : 64, | ||
"Blind" : 128, | ||
"Drunk" : 512, | ||
"Confused" : 1024, | ||
"StunImmune" : 2048, | ||
"Invisible" : 4096, | ||
"Paralyzed" : 8192, | ||
"Speedy" : 16384, | ||
"NinjaSpeedy" : 268435456, | ||
"Hallucinating" : 256, | ||
"Healing" : 131072, | ||
"Damaging" : 262144, | ||
"Berserk" : 524288, | ||
"Paused" : 1048576, | ||
"Stasis" : 2097152, | ||
"Invincible" : 8388608, | ||
"Invulnerable" : 16777216, | ||
"Armored" : 33554432, | ||
"ArmorBroken" : 67108864, | ||
"ArmorBrokenImmune" : 65536, | ||
"SlowedImmune" : 2147483648, | ||
"Unstable" : 536870912, | ||
"Darkness" : 1073741824, | ||
"Bleeding" : 32768 | ||
} | ||
|
||
effect1 = { | ||
"Swiftness" : 16, | ||
"ParalyzeImmune" : 2, | ||
"DazedImmune" : 1, | ||
"Petrified" : 4, | ||
"PetrifiedImmune" : 8, | ||
"Cursed" : 32, | ||
"CursedImmune" : 64, | ||
"Hidden" : 32768, | ||
"SamuraiBerserk" : 8388608, | ||
"Relentless" : 67108864, | ||
"Vengeance" : 134217728, | ||
"Alliance" : 536870912, | ||
"Grasp" : 4194304, | ||
"Bravery" : 262144, | ||
"Exhausted" : 524288, | ||
"JacketOffense" : 2, | ||
"JacketDefense" : 4 | ||
} | ||
|
||
effect2 = { | ||
"EmpoweredImmunity" : 8, | ||
"ConfusedImmunity" : 16, | ||
"WeakImmunity" : 32, | ||
"BlindImmunity" : 64, | ||
"QuietImmunity" : 128, | ||
"BleedingImmunity" : 256, | ||
"SickImmunity" : 512, | ||
"DrunkImmunity" : 1024, | ||
"HallucinatingImmunity" : 2048, | ||
"HexedImmunity" : 4096, | ||
"UnstableImmunity" : 8192, | ||
"DarknessImmunity" : 16384, | ||
"ExhaustedImmunity" : 32768, | ||
"StasisImmune" : 4194304, | ||
"CorruptedImmune" : 65536 | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
class PluginManager: | ||
|
||
|
||
def __init__(self): | ||
# key is plugin class, value is true if on else false | ||
self.plugins = {} | ||
# key is packet type, value is set of plugin classes (key for self.plugins) | ||
self.hooks = {} | ||
|
||
""" | ||
initialize all plugins. | ||
creates a dictionary with key | ||
returns true if success, false o.w. | ||
""" | ||
def initializePlugins(self) -> bool: | ||
|
||
import os | ||
for plugin in os.listdir("Plugins"): | ||
if plugin[-3:] == ".py": | ||
t = plugin.replace(".py", "") | ||
exec("from Plugins.{} import *".format(t)) | ||
try: | ||
# by default, the plugin is not active. | ||
if eval(t).load == True: | ||
self.plugins.update({eval(t + "()") : False}) | ||
except Exception as e: | ||
print("There was an error when loading plugins. Make sure you follow the naming convention when writing your own plugins.") | ||
print("Error:", e) | ||
return False | ||
|
||
print("[Initializer]: Successfully loaded {} plugins.".format(len(self.plugins))) | ||
return True | ||
|
||
|
||
|
||
""" | ||
Creates a dictionary with key = PacketType, value = key of plugins | ||
allows us to just call specific plugins on specific packets | ||
""" | ||
def initializeHookDictionary(self): | ||
for plugin in self.plugins: | ||
for hook in plugin.hooks: | ||
# add new packettype hook | ||
if hook not in self.hooks: | ||
self.hooks.update({hook : {plugin}}) | ||
# already exists | ||
else: | ||
self.hooks[hook].add(plugin) | ||
|
||
def initialize(self): | ||
if not self.initializePlugins(): | ||
return False | ||
self.initializeHookDictionary() | ||
return True |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# these imports are always necessary | ||
from valorlib.Packets.Packet import * | ||
from client import Client | ||
|
||
# this is a short tutorial on how to write a plugin that will **only edit packets, not send new ones.** | ||
# make sure the class name is capitalized, and matches the file's name. | ||
class Godmode: | ||
|
||
""" | ||
for each plugin, you need to instantiate a *class variable* called hook. | ||
make sure this is a set. | ||
this will tell the program what packets you intend to hook | ||
why? suppose you have 10 plugins that utilize NewTick. You don't want to reread | ||
newtick 10 times. Also, you only want to call the plugins which contain a newtick | ||
hook. Remember, the faster this proxy is, the faster it can route packets. | ||
""" | ||
|
||
hooks = {PacketTypes.PlayerHit, PacketTypes.GroundDamage} | ||
|
||
# also, make sure you put this class variable to tell the PluginManager whether to load this plugin or not. If this is absent, | ||
# the manager will throw an exception. | ||
load = True | ||
|
||
""" | ||
Next, you need to write functions that will handle each packet type in your hooks. | ||
Make sure your function name is on + the capitalization found in PacketTypes.py, otherwise your function will not be called. | ||
This is all you need to write. Here is an example | ||
def onPacketType(self, client: Client, packet: Packet, send: bool) | ||
client is an instance of client | ||
packet is an instance of the specific packet type your function will handle. | ||
send is whether or not this packet will be sent | ||
returns: (updated packet, send) | ||
send = true if you wish to send the packet, else false | ||
Below is an example of these handlers. Since godmode is just blocking the packet, we can just set send to false | ||
""" | ||
|
||
def onPlayerHit(self, client: Client, packet: PlayerHit, send: bool) -> (PlayerHit, bool): | ||
return (packet, False) | ||
|
||
def onGroundDamage(self, client: Client, packet: GroundDamage, send: bool) -> (GroundDamage, bool): | ||
return (packet, False) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
from valorlib.Packets.Packet import * | ||
from ConditionEffect import * | ||
from client import Client | ||
|
||
""" | ||
this does not work. works for like one bullet or something | ||
""" | ||
|
||
class Invulnerable: | ||
|
||
hooks = {PacketTypes.NewTick} | ||
load = False | ||
|
||
def onNewTick(self, client: Client, packet: NewTick, send: bool) -> (NewTick, bool): | ||
|
||
for obj in range(len(packet.statuses)): | ||
|
||
# got a packet that updates our stats | ||
if packet.statuses[obj].objectID == client.objectID: | ||
|
||
for s in range(len(packet.statuses[obj].stats)): | ||
|
||
if packet.statuses[obj].stats[s].statType == 29: | ||
packet.statuses[obj].stats[s].statValue |= effect0['Invulnerable'] | ||
break | ||
|
||
# if we didn't receive a packet that will update our stats, just add a new statdata object that does | ||
else: | ||
s = StatData() | ||
s.statType = 29 | ||
s.statValue = client.effect0bits | effect0['Invulnerable'] | ||
client.effect0bits |= effect0['Invulnerable'] | ||
packet.statuses[obj].stats.append(s) | ||
break | ||
|
||
# else if the newtick doesn't modify our stats, create a new objectstatusdata that gives speedy | ||
else: | ||
o = ObjectStatusData() | ||
o.objectID = client.objectID | ||
# doesn't even matter if position isn't valid | ||
o.pos = WorldPosData() | ||
s = StatData() | ||
s.statType = 29 | ||
s.statValue = client.effect0bits | effect0['Invulnerable'] | ||
client.effect0bits |= effect0['Invulnerable'] | ||
packet.statuses.append(o) | ||
|
||
|
||
return (packet, send) | ||
|
||
# here we also utilize packet injection to turn off the hack | ||
|
||
def shutdown(self, client: Client) -> None: | ||
|
||
packet2 = NewTick() | ||
packet2.tickID = 0 | ||
packet2.tickTime = 0 | ||
o = ObjectStatusData() | ||
o.objectID = client.objectID | ||
# doesn't even matter if position isn't valid | ||
o.pos = WorldPosData() | ||
s = StatData() | ||
s.statType = 29 | ||
# remove speedy | ||
if client.effect1bits & effect0['Invulnerable']: | ||
s.statValue = client.effect0bits - effect0['Invulnerable'] | ||
else: | ||
s.statValue = client.effect0bits | ||
o.stats.append(s) | ||
packet2.statuses.append(o) | ||
packet2 = CreatePacket(packet2) | ||
client.SendPacketToClient(packet2) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
from valorlib.Packets.Packet import * | ||
from ConditionEffect import * | ||
from client import Client | ||
|
||
class NoDebuff: | ||
|
||
""" | ||
Need to research a bit more into blocking the effect entirely. Only removes after new tick happens; client is in control of the behavior of status effect. | ||
This means you need some type of dict that tells you each enemy's bullet IDs, then join bullet ID with object ID in update packet probably. | ||
Search XML's next | ||
""" | ||
|
||
hooks = {PacketTypes.NewTick} | ||
load = True | ||
effect0Remove = ["Quiet", "Hallucinating", "Weak", "Slowed", "Sick", "Stunned", "Blind", "Drunk", "Confused", "Paralyzed", "Stasis", "ArmorBroken", "Darkness", "Unstable", "Bleeding"] | ||
|
||
def onNewTick(self, client: Client, packet: NewTick, send: bool) -> (NewTick, bool): | ||
|
||
|
||
for obj in range(len(packet.statuses)): | ||
if packet.statuses[obj].objectID == client.objectID: | ||
for s in range(len(packet.statuses[obj].stats)): | ||
# if we got a packet representing us and a conditioneffect statdata | ||
if packet.statuses[obj].stats[s].statType == 29: | ||
# for each debuff | ||
for remove in self.effect0Remove: | ||
# if the bit is on | ||
if packet.statuses[obj].stats[s].statValue & (1 << self.getExponent(effect0[remove])): | ||
# remove the bit | ||
packet.statuses[obj].stats[s].statValue -= effect0[remove] | ||
# keep track of the state | ||
client.effect0bits -= effect0[remove] | ||
break | ||
# if we did not get a packet, just inject a new one without bad status effects | ||
else: | ||
s = StatData() | ||
s.statType = 29 | ||
for remove in self.effect0Remove: | ||
if client.effect0bits & (1 << self.getExponent(effect0[remove])): | ||
client.effect0bits -= effect0[remove] | ||
s.statValue = client.effect0bits | ||
packet.statuses[obj].stats.append(s) | ||
|
||
return (packet, send) | ||
|
||
# given a number of the form 2^k, k >= 1 returns k | ||
# if you give it a number x where 2^k <= x < 2^{k+1}, it will return k. | ||
def getExponent(self, num): | ||
cnt = 0 | ||
while num != 1: | ||
num = num // 2 | ||
cnt += 1 | ||
return cnt |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
from valorlib.Packets.Packet import * | ||
from client import Client | ||
|
||
class NoProjectile: | ||
|
||
hooks = {PacketTypes.EnemyShoot} | ||
load = True | ||
|
||
def onEnemyShoot(self, client: Client, packet: Packet, send: bool) -> (EnemyShoot, bool): | ||
return (packet, False) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
from valorlib.Packets.Packet import * | ||
from ConditionEffect import * | ||
from client import Client | ||
|
||
""" | ||
here is a more involved situation where we edit the NewTick packet. | ||
""" | ||
|
||
class Speedy: | ||
|
||
hooks = {PacketTypes.NewTick} | ||
load = True | ||
|
||
def onNewTick(self, client: Client, packet: NewTick, send: bool) -> (NewTick, bool): | ||
|
||
for obj in range(len(packet.statuses)): | ||
|
||
# got a packet that updates our stats | ||
if packet.statuses[obj].objectID == client.objectID: | ||
|
||
for s in range(len(packet.statuses[obj].stats)): | ||
|
||
if packet.statuses[obj].stats[s].statType == 29: | ||
packet.statuses[obj].stats[s].statValue |= effect0['Speedy'] | ||
break | ||
|
||
# if we didn't receive a packet that will update our stats, just add a new statdata object that does | ||
else: | ||
s = StatData() | ||
s.statType = 29 | ||
s.statValue = client.effect0bits | effect0['Speedy'] | ||
# update the internal bit state to account for 1+ status effect mods | ||
client.effect0bits |= effect0['Speedy'] | ||
packet.statuses[obj].stats.append(s) | ||
break | ||
|
||
# else if the newtick doesn't modify our stats, create a new objectstatusdata that gives speedy | ||
else: | ||
o = ObjectStatusData() | ||
o.objectID = client.objectID | ||
# doesn't even matter if position isn't valid | ||
o.pos = WorldPosData() | ||
s = StatData() | ||
s.statType = 29 | ||
s.statValue = client.effect0bits | effect0['Speedy'] | ||
client.effect0bits |= effect0['Speedy'] | ||
packet.statuses.append(o) | ||
|
||
|
||
|
||
return (packet, send) | ||
|
||
def shutdown(self, client: Client) -> None: | ||
|
||
packet2 = NewTick() | ||
packet2.tickID = 0 | ||
packet2.tickTime = 0 | ||
o = ObjectStatusData() | ||
o.objectID = client.objectID | ||
# doesn't even matter if position isn't valid | ||
o.pos = WorldPosData() | ||
s = StatData() | ||
s.statType = 29 | ||
# remove speedy, this is why we keep the internal state | ||
if client.effect0bits & effect0['Speedy']: | ||
s.statValue = client.effect0bits - effect0['Speedy'] | ||
client.effect0bits -= effect0['Speedy'] | ||
else: | ||
s.statValue = client.effect0bits | ||
o.stats.append(s) | ||
packet2.statuses.append(o) | ||
packet2 = CreatePacket(packet2) | ||
client.SendPacketToClient(packet2) |
Oops, something went wrong.