Created
November 30, 2019 20:43
-
-
Save iamgreaser/0a63367df083749a7d5d7c033c926a8c to your computer and use it in GitHub Desktop.
malsa076.py
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
""" | |
MALSA 0.76: Make AoS Less Shit Again | |
Instantly turns a 0.75 server into a 0.76 server. | |
Version 4 | |
Author: GreaseMonkey | |
Changelog: | |
Version 4: 2019-12-01 | |
- Updated so that it works on this year's piqueserver. | |
- Dropped support for pyspades and pysnip. | |
Version 3: 2018-08-28 | |
- Added piqueserver support. | |
Version 2: 2018-08-27 | |
- Added damage falloff. | |
Version 1: 2018-08-26 | |
- Initial release. | |
""" | |
# vim: set sts=4 sw=4 et : | |
import math | |
import zlib | |
import pyspades.constants | |
from pyspades.constants import TORSO, HEAD, ARMS, LEGS | |
import pyspades.collision | |
import pyspades.contained | |
import pyspades.master | |
import pyspades.server | |
import pyspades.weapon | |
class MalsaWorldUpdate(object): | |
def __init__(self): | |
self.items = None | |
def write(self, data): | |
data.writeByte(int(pyspades.contained.WorldUpdate.id)) | |
for (idx, item,) in enumerate(self.items): | |
if not all(map(lambda vec: all(map(lambda el: el == 0.0, vec)), | |
item)): | |
data.writeByte(idx) | |
for vec in item: | |
for el in vec: | |
data.writeFloat(el, False) | |
class MalsaMapStart(object): | |
def __init__(self): | |
self.size = None | |
self.crc = None | |
self.map_name = None | |
def write(self, data): | |
data.writeByte(int(pyspades.contained.MapStart.id)) | |
data.writeInt(self.size, True, False) | |
# TODO: get CRC | |
#data.writeInt(self.crc, True, False) | |
#data.writeString(self.map_name) | |
def apply_system_patches(): | |
# | |
# Version changes | |
# | |
pyspades.constants.GAME_VERSION = 4 | |
# | |
# Weapon changes | |
# | |
# Rifle | |
pyspades.weapon.Rifle.delay = 0.6 | |
pyspades.weapon.Rifle.ammo = 8 | |
pyspades.weapon.Rifle.stock = 48 | |
pyspades.weapon.Rifle.reload_time = 2.5 | |
pyspades.weapon.Rifle.slow_reload = False | |
pyspades.weapon.Rifle.damage[TORSO] = 60 | |
pyspades.weapon.Rifle.damage[HEAD] = 250 | |
pyspades.weapon.Rifle.damage[ARMS] = 50 | |
pyspades.weapon.Rifle.damage[LEGS] = 50 | |
# SMG | |
# Delay: Vanilla uses 0.1 explicitly but in practice gets 0.112. | |
# OpenSpades uses 0.11 explicitly. | |
pyspades.weapon.SMG.delay = 0.11 | |
pyspades.weapon.SMG.ammo = 30 | |
pyspades.weapon.SMG.stock = 150 | |
pyspades.weapon.SMG.reload_time = 2.5 | |
pyspades.weapon.SMG.slow_reload = False | |
pyspades.weapon.SMG.damage[TORSO] = 40 | |
pyspades.weapon.SMG.damage[HEAD] = 60 | |
pyspades.weapon.SMG.damage[ARMS] = 20 | |
pyspades.weapon.SMG.damage[LEGS] = 20 | |
# Shotgun | |
pyspades.weapon.Shotgun.delay = 0.8 | |
pyspades.weapon.Shotgun.ammo = 8 | |
pyspades.weapon.Shotgun.stock = 48 | |
pyspades.weapon.Shotgun.reload_time = 0.4 | |
pyspades.weapon.Shotgun.slow_reload = True | |
pyspades.weapon.Shotgun.damage[TORSO] = 40 | |
pyspades.weapon.Shotgun.damage[HEAD] = 60 | |
pyspades.weapon.Shotgun.damage[ARMS] = 20 | |
pyspades.weapon.Shotgun.damage[LEGS] = 20 | |
# Damage falloff | |
def get_damage(self, value, position1, position2): | |
falloff = 1 - ((pyspades.collision.distance_3d_vector(position1, position2)**1.5)*0.0004) | |
return math.ceil(self.damage[value] * falloff) | |
pyspades.weapon.BaseWeapon.get_damage = get_damage | |
pyspades.weapon.Rifle.get_damage = get_damage | |
pyspades.weapon.SMG.get_damage = get_damage | |
pyspades.weapon.Shotgun.get_damage = get_damage | |
# | |
# Master server | |
# | |
pyspades.master.STAGING = 1 | |
pyspades.master.PORT = 32885 | |
def apply_script(protocol, connection, config): | |
# | |
# Connection | |
# | |
class MalsaConnection(connection): | |
def send_map(self, data = None, *args, **kwargs): | |
if data is not None: | |
self.map_data = data | |
map_start = MalsaMapStart() | |
map_start.size = data.get_size() | |
# TODO: get CRC | |
#map_start.crc = zlib.crc32(self.protocol.map_info.data) & 0xFFFFFFFF | |
#map_start.map_name = self.protocol.map_info.rot_info.get_map_name() | |
self.send_contained(map_start) | |
data = None | |
elif self.map_data is None: | |
return | |
return connection.send_map(self, data, *args, **kwargs) | |
# | |
# Protocol | |
# | |
class MalsaProtocol(protocol): | |
version = 4 | |
def send_contained(self, contained, *args, **kwargs): | |
#print("Contained ID %d" % (contained.id,)) | |
if contained.id == pyspades.contained.WorldUpdate.id: | |
#print("Wrap %s somehow" % (repr(contained),)) | |
world_update = MalsaWorldUpdate() | |
world_update.items = contained.items | |
contained = world_update | |
else: | |
#print("Class: %s" % (repr(contained.__class__.__name__),)) | |
pass | |
return protocol.send_contained(self, contained, *args, **kwargs) | |
# | |
# We are done. | |
# | |
return MalsaProtocol, MalsaConnection | |
# | |
# Apply system patches immediately. | |
# | |
apply_system_patches() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment