Skip to content
This repository has been archived by the owner on Aug 6, 2022. It is now read-only.

Commit

Permalink
not so first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
swrlly committed May 18, 2021
0 parents commit 2d5fbe3
Show file tree
Hide file tree
Showing 18 changed files with 1,420 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
parsers
__pycache__
Plugins/__pycache__
3 changes: 3 additions & 0 deletions .gitmodules
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
70 changes: 70 additions & 0 deletions ConditionEffect.py
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
}

54 changes: 54 additions & 0 deletions PluginManager.py
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
44 changes: 44 additions & 0 deletions Plugins/Godmode.py
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)
72 changes: 72 additions & 0 deletions Plugins/Invulnerable.py
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)
53 changes: 53 additions & 0 deletions Plugins/NoDebuff.py
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
10 changes: 10 additions & 0 deletions Plugins/NoProjectile.py
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)
73 changes: 73 additions & 0 deletions Plugins/Speedy.py
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)
Loading

0 comments on commit 2d5fbe3

Please sign in to comment.