Пример #1
0
def check_update(logger: Logger, repo: str, rpath: str, last_update: float):
    if not can_check:
        logger.warning(f"cant check update of {repo} - {rpath}")

    key = f"{repo} - {rpath}"
    cache = _storage.data.setdefault('cache', dict()).setdefault(key, dict())
    headers_ = headers.copy()
    headers_["If-None-Match"] = cache.setdefault('etag', '')

    try:
        q = get(f"{domain}/repos/{repo}/commits", {'path': rpath, 'page': '1', 'per_page': '1', }, headers=headers_)
    except Exception as e:
        logger.warning(f"cant check update of {repo} - {rpath}: {e}")
    else:
        if q.status_code != 304:
            data = q.json()
            if q.status_code != 200:
                logger.warning(q.json()["message"])
                return
            cache['etag'] = q.headers['ETag']
            new_timestamp = datetime.strptime(data[0]["commit"]["author"]["date"], '%Y-%m-%dT%H:%M:%SZ').replace(tzinfo=timezone.utc).timestamp()
            cache['timestamp'] = int(new_timestamp)
            _storage.save()

        t = cache['timestamp']
        if t > last_update:
            logger.warning(f"There is a update at {datetime.fromtimestamp(t)} on https://github.com/{repo}")
        else:
            logger.debug(f"{repo} - {rpath} is up to date")
    _storage.save()
Пример #2
0
def get_last_update(name: Optional[str], current_hash: str, logger: Logger):
    if name is None:
        data_dir = _storage.data.setdefault('core', dict())
    else:
        data_dir = _storage.data.setdefault('plugins', dict()).setdefault(name, dict())
    if 'time' not in data_dir or 'hash' not in data_dir or data_dir['hash'] != current_hash:
        logger.debug("last update time update")
        data_dir['time'] = time()
        data_dir['hash'] = current_hash
    _storage.save()
    return data_dir['time']
Пример #3
0
from ctypes import sizeof
from datetime import datetime
from typing import Optional

from FFxivPythonTrigger.Logger import Logger

from .Structs import ServerAddStatusEffect, NetworkEventBase

_logger = Logger("XivNetwork/ProcessAddStatusEffect")
size = sizeof(ServerAddStatusEffect)


class AddStatusEffectEvent(NetworkEventBase):
    id = "network/add_status_effect"
    name = "network add status effect event"

    def __init__(self, raw_msg, msg_time):
        super().__init__(raw_msg, msg_time)
        self.actor_id = raw_msg.header.actor_id
        self.actor_id2 = raw_msg.actor_id
        self.current_hp = raw_msg.current_hp
        self.max_hp = raw_msg.max_hp
        self.current_mp = raw_msg.current_mp
        self.damage_shield = raw_msg.damage_shield
        self.effects = raw_msg.effects[:min(raw_msg.effect_count, 4)]

    def text(self):
        return f"update {hex(self.actor_id)[2:]};{self.current_hp}(+{self.damage_shield}%)/{self.max_hp};{self.current_mp}/10000;{[e.get_data() for e in self.effects]}"


def get_event(msg_time: datetime,
Пример #4
0
from ctypes import *

from FFxivPythonTrigger.Logger import Logger
from FFxivPythonTrigger.memory.StructFactory import OffsetStruct
from ..Structs import RecvNetworkEventBase

ServerEventPlay = OffsetStruct(
    {
        'target_id': c_uint,
        'unk0': c_uint,
        'event_id': c_ushort,
        'category': c_ushort,
    }, 0x28)

_logger = Logger("XivNetwork/ProcessServerEventPlay")
size = sizeof(ServerEventPlay)


class ServerEventPlayEvent(RecvNetworkEventBase):
    id = "network/recv_event_play"
    name = "network recv event play"

    def text(self):
        return f"event play {self.raw_msg.category}-{self.raw_msg.event_id} (target:{hex(self.raw_msg.target_id)})"


def get_event(msg_time, header, raw_msg):
    if len(raw_msg) < size:
        _logger.warning("message is too short to parse:[%s]" % raw_msg.hex())
        return
    return ServerEventPlayEvent(msg_time, header,
Пример #5
0
from math import degrees

from FFxivPythonTrigger.Logger import Logger
from FFxivPythonTrigger.memory.StructFactory import OffsetStruct
from ..Structs import SendNetworkEventBase, Vector3

ClientPositionSet = OffsetStruct(
    {
        'r': (c_float, 0),
        'unk0': (c_ushort, 0x4),
        'unk1': (c_ushort, 0x6),
        'pos': (Vector3, 0x8),
        'unk2': (c_uint, 0x14),
    }, 24)

_logger = Logger("XivNetwork/ProcessClientPositionSet")
size = sizeof(ClientPositionSet)


class PositionSetEvent(SendNetworkEventBase):
    id = "network/position_set"
    name = "network send self position set"

    def __init__(self, msg_time, header, raw_msg):
        super().__init__(msg_time, header, raw_msg)
        self.new_r = raw_msg.r
        self.new_pos = raw_msg.pos

    def text(self):
        return "move to ({:.2F},{:.2F},{:.2F}) facing {:.2F}°".format(
            self.new_pos.x, self.new_pos.y, self.new_pos.z,
    'duration': c_float,
    'source_actor_id': c_uint,
})

ServerAddStatusEffect = OffsetStruct({
    'related_action_sequence': c_uint,
    'actor_id': c_uint,
    'current_hp': c_uint,
    'max_hp': c_uint,
    'current_mp': c_ushort,
    'unk0': c_ushort,
    'damage_shield': c_ubyte,
    'effect_count': c_ubyte,
    'unk1': c_ushort,
    'effects': ServerStatusEffectAddEntry * 4,
    # 'unk2': c_uint,
})

_logger = Logger("XivNetwork/ProcessAddStatusEffect")
size = sizeof(ServerAddStatusEffect)
_logger.debug("size: %d" % size)


def get_event(msg_time: datetime, header,
              raw_msg: bytearray) -> Optional[RecvNetworkEventBase]:
    if len(raw_msg) < size:
        _logger.warning("message is too short to parse:[%s]" % raw_msg.hex())
        return
    return RecvAddStatusEffectEvent(msg_time, header,
                                    ServerAddStatusEffect.from_buffer(raw_msg))
    @cached_property
    def item(self):
        if self.item_id:
            return item_sheet[self.item_id]


ServerMarketBoardItemList = OffsetStruct({
    'items': MarketBoardItemEntry * 10,
    'list_index_end': c_ubyte,
    'list_index_start': c_ubyte,
    'request_id': c_ushort,
    'unk1': c_uint,
}, 1528)

_logger = Logger("XivNetwork/ProcessMarketBoardItemList")
size = sizeof(ServerMarketBoardItemList)
item_sheet = realm.game_data.get_sheet('Item')


class ServerMarketBoardItemListEvent(RecvNetworkEventBase):
    id = "network/recv_market_board_item_list"
    name = "network recv market board item list"

    def __init__(self, msg_time, header, raw_msg):
        super().__init__(msg_time, header, raw_msg)
        self.item_id = self.raw_msg.items[0].item_id
        self.item_count = 0
        for item in self.raw_msg.items:
            if item.item_id:
                self.item_count += 1
Пример #8
0
from ctypes import sizeof
from datetime import datetime
from typing import Optional

from FFxivPythonTrigger.Logger import Logger

from ..Structs import ServerActorGauge, RecvNetworkEventBase

_logger = Logger("XivNetwork/ProcessActorGauge")
size = sizeof(ServerActorGauge)


class RecvActorGaugeEvent(RecvNetworkEventBase):
    id = "network/actor_gauge"
    name = "network actor gauge event"

    def __init__(self, msg_time, raw_msg):
        super().__init__(msg_time, raw_msg)
        self.buffer = bytearray(raw_msg.buffer)

    def text(self):
        return self.buffer.hex()


def get_event(msg_time: datetime,
              raw_msg: bytearray) -> Optional[RecvNetworkEventBase]:
    if len(raw_msg) < size:
        _logger.warning("message is too short to parse:[%s]" % raw_msg.hex())
        return
    return RecvActorGaugeEvent(msg_time, ServerActorGauge.from_buffer(raw_msg))
Пример #9
0
from ctypes import sizeof
from datetime import datetime
from typing import Optional

from FFxivPythonTrigger.Logger import Logger

from ..Structs import ServerActionEffect1, ServerActionEffect8, ServerActionEffect16
from ..Structs import ServerActionEffect24, ServerActionEffect32, ServerActionEffectHeader
from ..Structs import ServerActionEffectDisplayType, RecvNetworkEventBase as EventBase

_logger = Logger("XivNetwork/ProcessAbility")

header_size = sizeof(ServerActionEffectHeader)
a1_size = sizeof(ServerActionEffect1)
a8_size = sizeof(ServerActionEffect8)
a16_size = sizeof(ServerActionEffect16)
a24_size = sizeof(ServerActionEffect24)
a32_size = sizeof(ServerActionEffect32)


def get_event1(msg_time: datetime, raw_msg: bytearray) -> Optional[EventBase]:
    if len(raw_msg) < a1_size:
        _logger.warning(
            f"message is too short to parse as ServerActionEffect1 {len(raw_msg)}/{a1_size} [{raw_msg.hex()}]"
        )
    else:
        return get_event(msg_time, ServerActionEffect1.from_buffer(raw_msg), 1)


def get_event8(msg_time: datetime, raw_msg: bytearray) -> Optional[EventBase]:
    if len(raw_msg) < a8_size:
Пример #10
0
from datetime import datetime, timezone
from time import time
from traceback import format_exc
from typing import Optional

from requests import get
import urllib.request
from urllib.error import HTTPError, URLError
from socket import timeout

from FFxivPythonTrigger.Logger import Logger
from FFxivPythonTrigger.Storage import ModuleStorage, BASE_PATH

domain = "https://api.github.com"
_logger = Logger("CheckGitUpdater")
_storage = ModuleStorage(BASE_PATH / "Update")
headers = {
    'User-Agent': 'FFxivPythonTrigger',
}


def test_url(url):
    try:
        return urllib.request.urlopen(url, timeout=3).getcode() == 200
    except (HTTPError, URLError) as error:
        _logger.warning('Data of [%s] not retrieved because %s' % (url, error))
    except timeout:
        _logger.warning('socket timed out - URL [%s]' % url)
    return False

Пример #11
0
from FFxivPythonTrigger.SaintCoinach import realm
from FFxivPythonTrigger.Logger import Logger
from .GetInteger import *
from .Keys import *

_logger = Logger("chat_log/messages")

world_sheet = realm.game_data.get_sheet('World')
item_sheet = realm.game_data.get_sheet('Item')
territory_type_sheet = realm.game_data.get_sheet('TerritoryType')
map_sheet = realm.game_data.get_sheet('Map')
status_sheet = realm.game_data.get_sheet('Status')
quest_sheet = realm.game_data.get_sheet('Quest')
completion_sheet = realm.game_data.get_sheet('Completion')


def extract_special_message(raw: bytearray):
    if raw.pop(0) != START_BYTE:
        raise Exception("Special Message decode, start byte mismatch")
    type_code = raw.pop(0)
    length = raw.pop(0)
    if len(raw) < length:
        raise Exception("Special Message length invalid")
    data = raw[:length]
    if data[-1] == END_BYTE: del data[-1]
    del raw[:length]
    return type_code, data


def pack_special_message(type_code: int, data: bytearray = bytearray()):
    rtn = bytearray([START_BYTE, type_code, len(data) + 1])
                'selling_count': c_ubyte,
                'market': c_ubyte,
                'class_job': c_ubyte,
                'level': c_ubyte,
                'sell_end_time': c_uint,
                'mission_id': c_uint,
                'adv_end_time': c_uint,
                'reserved': c_ubyte,
                '_name': c_char * 39,
            }, 80, ['name'])):
    @property
    def name(self):
        return self._name.decode('utf-8', errors='ignore')


_logger = Logger("XivNetwork/ProcessServerRetainerInformation")
size = sizeof(ServerRetainerInformation)


class ServerRetainerInformationEvent(RecvNetworkEventBase):
    id = "network/recv_retainer_info"
    name = "network recv retainer info"

    def text(self):
        return f"{self.raw_msg.name} {hex(self.raw_msg.retainer_id)}/{hex(self.raw_msg.server_id)}" if self.raw_msg.reserved else 'n/a'


def get_event(msg_time, header, raw_msg):
    if len(raw_msg) < size:
        _logger.warning("message is too short to parse:[%s]" % raw_msg.hex())
        return
        OffsetStruct(
            {
                'container_sequence': c_uint,
                'container_id': c_ushort,
                'slot': c_ushort,
                'count': c_uint,
                'unk0': c_uint,
                'item_id': c_uint,
                'unk1': c_uint,
                'unk2': c_uint,
                'unk3': c_uint,
            }, 32)):
    pass


_logger = Logger("XivNetwork/ProcessServerCurrencyCrystalInfo")
size = sizeof(ServerCurrencyCrystalInfo)
item_sheet = realm.game_data.get_sheet('Item')


class ServerCurrencyCrystalInfoEvent(RecvNetworkEventBase):
    id = "network/recv_currency_crystal_info"
    name = "network recv currency crystal info"

    def __init__(self, msg_time, header, raw_msg):
        super().__init__(msg_time, header, raw_msg)
        self.container_id = self.raw_msg.container_id
        self.slot = self.raw_msg.slot
        self.count = self.raw_msg.count

    @cached_property
Пример #14
0
from ctypes import sizeof

from FFxivPythonTrigger.Logger import Logger
from ..Structs import SendNetworkEventBase, ClientEventAction, header_size

_logger = Logger("XivNetwork/ProcessClientEventAction")
size = sizeof(ClientEventAction)


class ClientEventActionEvent(SendNetworkEventBase):
    id = "network/send_event_action"
    name = "network send event action"

    def text(self):
        return f"event action {self.raw_msg.category}-{self.raw_msg.event_id}"


def get_event(msg_time, raw_msg):
    if len(raw_msg) < size + header_size:
        _logger.warning("message is too short to parse:[%s]" % raw_msg.hex())
        return
    return ClientEventActionEvent(
        msg_time, ClientEventAction.from_buffer(raw_msg[header_size:]))
Пример #15
0
    'param1': c_uint,
    'param2': c_uint,
    'param3': c_uint,
    'param4': c_uint,
    'padding1': c_uint,
})


def dot_hot_event(msg_time, header, msg):
    return (HotEvent if msg.param2 == 4 else
            DotEvent if msg.param2 == 3 else UnknownDotHotEvent)(msg_time,
                                                                 header, msg)


size = sizeof(ServerActorControl142)
_logger = Logger("XivNetwork/ProcessActorControl142")
_unknown_category = set()
_unknown_dot_hot_type = set()
_logger.debug("size: %d" % size)

category_event_map = {
    6: DeathEvent,
    22: EffectUpdateEvent,
    54: TargetableEvent,
    35: TetherEvent,
    5: JobChangeEvent,
    21: EffectRemoveEvent,
    23: dot_hot_event,
}

Пример #16
0
# prev: 上一个技能名
# effect: 函数,获取buff层数/回合 e.g.effect("內静")
###############

import re
from itertools import chain

from FFxivPythonTrigger.Logger import Logger
from FFxivPythonTrigger.Storage import get_module_storage
from FFxivPythonTrigger.MacroParser import Macro, MacroFinish
from pathlib import Path

from .. import Solver
from ...simulator.Craft import CheckUnpass

_logger = Logger("CraftMacroSolver")
_storage = get_module_storage("MacroCraft")

macro_dir = Path(__file__).parent / 'macros'
macro_craft_tag_regex = re.compile(
    r"#CraftMacro:\[(?P<key>[^]]+)]:(?P<arg>[^\n]+)\n")
macro_max_size = 100
macro_pairing = dict()
macros = list()
recipe_pair_id = dict()
recipe_pair_name = dict()
macro_file = "*.macro"


class MacroOversize(Exception):
    pass
from ctypes import sizeof
from datetime import datetime
from typing import Optional

from FFxivPythonTrigger.Logger import Logger

from ..Structs import ServerActorControlCategory, ServerActorControl143, RecvNetworkEventBase

_logger = Logger("XivNetwork/ProcessActorControl143")
_unknown_category = set()
_unknown_director_update = set()

size = sizeof(ServerActorControl143)


class InitialCommenceEvent(RecvNetworkEventBase):
    id = "network/actor_control/director_update/initial_commence"
    name = "network initial commence event"

    def __init__(self, msg_time, raw_msg):
        super().__init__(msg_time, raw_msg)
        self.content = raw_msg.param1
        self.time = raw_msg.param3

    def text(self):
        return f"{self.content}({self.time}s)"


class RecommenceEvent(InitialCommenceEvent):
    id = "network/actor_control/director_update/recommence"
    name = "network recommence event"
from ctypes import sizeof
from datetime import datetime
from typing import Optional

from FFxivPythonTrigger.Logger import Logger

from .Structs import ServerUpdateHpMpTp, RecvNetworkEventBase

_logger = Logger("XivNetwork/ProcessActorUpdateHpMpTp")
size = sizeof(ServerUpdateHpMpTp)


class RecvActorUpdateHpMpTpEvent(RecvNetworkEventBase):
    id = "network/actor_update_hp_mp_tp"
    name = "network actor update hp mp tp event"

    def __init__(self, raw_msg, msg_time):
        super().__init__(raw_msg, msg_time)
        self.actor_id = raw_msg.header.actor_id
        self.current_hp = raw_msg.current_hp
        self.current_mp = raw_msg.current_mp

    def text(self):
        return f"{hex(self.actor_id)[2:]} - {self.current_hp},{self.current_mp}"


def get_event(msg_time: datetime,
              raw_msg: bytearray) -> Optional[RecvNetworkEventBase]:
    if len(raw_msg) < size:
        _logger.warning("message is too short to parse:[%s]" % raw_msg.hex())
        return
Пример #19
0
from FFxivPythonTrigger.memory import scan_address
from FFxivPythonTrigger.Logger import Logger
from FFxivPythonTrigger.Storage import get_module_storage
from FFxivPythonTrigger.AddressManager import AddressManager

_logger = Logger("XivMem/AddressManager")
_storage = get_module_storage("XivMem")
_am = AddressManager(_storage.data, _logger)

##########
# actor table
##########
actor_table_sig = "48 8d ?? ?? ?? ?? ?? e8 ?? ?? ?? ?? 48 8b ?? 48 8b ?? 48 8d ?? ?? ?? ?? ?? " \
                  "e8 ?? ?? ?? ?? 48 8d ?? ?? ?? ?? ?? ba ?? ?? ?? ?? e8 ?? ?? ?? ?? 89 2f"
actor_table_addr = _am.get("actor table",
                           scan_address,
                           actor_table_sig,
                           cmd_len=7)

##########
# combat data
##########
combo_state_sig = "f3 0f ?? ?? ?? ?? ?? ?? f3 0f ?? ?? ?? e8 ?? ?? ?? ?? 48 8b ?? 48 8b ?? 0f b7"
combo_state_addr = _am.get("combo state",
                           scan_address,
                           combo_state_sig,
                           cmd_len=8)

skill_queue_sig = "44 89 2d ?? ?? ?? ?? f3 0f 11 05 ?? ?? ?? ??"
skill_queue_addr = _am.get("skill queue",
                           scan_address,
Пример #20
0
from ctypes import *

from FFxivPythonTrigger.Logger import Logger
from FFxivPythonTrigger.memory.StructFactory import OffsetStruct
from ..Structs import RecvNetworkEventBase

ServerEventFinish = OffsetStruct({
    'event_id': c_ushort,
    'category': c_ushort,
}, 0x10)

_logger = Logger("XivNetwork/ProcessServerEventFinish")
size = sizeof(ServerEventFinish)


class ServerEventFinishEvent(RecvNetworkEventBase):
    id = "network/recv_event_finish"
    name = "network recv event finish"

    def text(self):
        return f"event finish {self.raw_msg.category}-{self.raw_msg.event_id}"


def get_event(msg_time, header, raw_msg):
    if len(raw_msg) < size:
        _logger.warning("message is too short to parse:[%s]" % raw_msg.hex())
        return
    return ServerEventFinishEvent(msg_time, header, ServerEventFinish.from_buffer(raw_msg))
Пример #21
0
from ctypes import sizeof

from FFxivPythonTrigger.Logger import Logger
from ..Structs import RecvNetworkEventBase, ServerEventStart, header_size

_logger = Logger("XivNetwork/ProcessServerEventStart")
size = sizeof(ServerEventStart)


class ServerEventStartEvent(RecvNetworkEventBase):
    id = "network/recv_event_start"
    name = "network recv event start"

    def text(self):
        return f"event start {self.raw_msg.category}-{self.raw_msg.event_id} (target:{hex(self.raw_msg.target_id)})"


def get_event(msg_time, raw_msg):
    if len(raw_msg) < size + header_size:
        _logger.warning("message is too short to parse:[%s]" % raw_msg.hex())
        return
    return ServerEventStartEvent(
        msg_time, ServerEventStart.from_buffer(raw_msg, header_size))
Пример #22
0
            self.current = 0


class WaitTimeoutException(Exception):
    def __init__(self):
        super(WaitTimeoutException, self).__init__("Wait Timeout")


def wait_until(statement: Callable[[], any], timeout: float = None, period: float = 0.1):
    temp = statement()
    start = time.perf_counter()
    while temp is None:
        if timeout is not None and time.perf_counter() - start >= timeout:
            raise WaitTimeoutException()
        time.sleep(period)
        temp = statement()
    return temp


_err_logger = Logger("ErrorCatcher")


def err_catch(func):
    def warper(*args, **kwargs):
        try:
            func(*args, **kwargs)
        except Exception:
            _err_logger.error(format_exc())

    return warper
Пример #23
0
from FFxivPythonTrigger.Logger import Logger
from FFxivPythonTrigger import FFxiv_Version

from ..Structs import RecvNetworkEventBase, ServerMessageHeader, header_size
from .Opcodes import opcodes
from . import AddStatusEffect, Ability, ActorCast, ActorControl142, StatusEffectList, ActorControl143, Ping
from . import ActorControl144, ActorGauge, ActorUpdateHpMpTp, EventStart, EventPlay, EventFinish, CraftStatus

_logger = Logger("XivNetwork/RecvProcessors")

_processors = {
    'StatusEffectList': StatusEffectList.get_event,
    'StatusEffectList2': StatusEffectList.get_event2,
    'BossStatusEffectList': StatusEffectList.get_eventB,
    'Ability1': Ability.get_event1,
    'Ability8': Ability.get_event8,
    'Ability16': Ability.get_event16,
    'Ability24': Ability.get_event24,
    'Ability32': Ability.get_event32,
    'ActorCast': ActorCast.get_event,
    'AddStatusEffect': AddStatusEffect.get_event,
    'ActorControl142': ActorControl142.get_event,
    'ActorControl143': ActorControl143.get_event,
    'ActorControl144': ActorControl144.get_event,
    'UpdateHpMpTp': ActorUpdateHpMpTp.get_event,
    'ActorGauge': ActorGauge.get_event,
    'Ping': Ping.get_event,
    "EventStart": EventStart.get_event,
    "EventFinish": EventFinish.get_event,
    "EventPlay": EventPlay.get_event,
    "CraftStatus": CraftStatus.get_event,
Пример #24
0
from ctypes import sizeof
from datetime import datetime
from typing import Optional

from FFxivPythonTrigger.Logger import Logger

from .Structs import ServerActorCast,NetworkEventBase

_logger = Logger("XivNetwork/ProcessActorCast")
size = sizeof(ServerActorCast)


class ActorCastEvent(NetworkEventBase):
    id = "network/actor_cast"
    name = "network actor cast event"

    def __init__(self, raw_msg, msg_time):
        super().__init__(raw_msg, msg_time)
        self.source_id = raw_msg.header.actor_id
        self.target_id = raw_msg.target_id
        self.action_id = raw_msg.action_id
        self.cast_time = raw_msg.cast_time

    def text(self):
        return f"{hex(self.source_id)[2:]} is casting {self.action_id} on {hex(self.target_id)[2:]} on {self.cast_time}s"


def get_event(msg_time: datetime, raw_msg: bytearray) -> Optional[NetworkEventBase]:
    if len(raw_msg) < size:
        _logger.warning("message is too short to parse:[%s]" % raw_msg.hex())
        return
Пример #25
0
from ctypes import sizeof
from datetime import datetime
from typing import Optional

from FFxivPythonTrigger.Logger import Logger

from .Structs import ServerStatusEffectList, ServerStatusEffectList2, ServerBossStatusEffectList, RecvNetworkEventBase

_logger = Logger("XivNetwork/ProcessStatusEffectListEffect")
size = sizeof(ServerStatusEffectList)
size2 = sizeof(ServerStatusEffectList2)
sizeB = sizeof(ServerBossStatusEffectList)


class RecvStatusEffectListEvent(RecvNetworkEventBase):
    id = "network/status_effect_list"
    name = "network status effect list event"

    def __init__(self, raw_msg, msg_time):
        super().__init__(raw_msg, msg_time)
        self.actor_id = raw_msg.header.actor_id
        self.current_hp = raw_msg.current_hp
        self.max_hp = raw_msg.max_hp
        self.current_mp = raw_msg.current_mp
        self.max_mp = raw_msg.max_mp
        self.damage_shield = raw_msg.damage_shield
        self.levels = (raw_msg.level_1, raw_msg.level_2, raw_msg.level_3)
        self.effects = [e for e in raw_msg.effects if e.effect_id]

    def text(self):
        return f"update {hex(self.actor_id)[2:]};{self.current_hp}(+{self.damage_shield}%)/{self.max_hp};{self.current_mp}/{self.max_mp};{[e.get_data() for e in self.effects]}"
Пример #26
0
from FFxivPythonTrigger.memory import scan_pattern, StructFactory, write_bytes, read_memory
from FFxivPythonTrigger.Logger import Logger
from FFxivPythonTrigger.Storage import get_module_storage
from FFxivPythonTrigger.AddressManager import AddressManager
from FFxivPythonTrigger import FFxiv_Version, PluginBase, api
from ctypes import c_ubyte, addressof
"""
patch code to skip cutscene in some zone
command:    @cutscene
format:     /e @cutscene [p(patch)/d(dispatch)]
"""

command = "@cutscene"

_logger = Logger("CutsceneSkipper")
_storage = get_module_storage("CutsceneSkipper")
sig = "75 33 48 8B 0D ?? ?? ?? ?? BA ?? 00 00 00 48 83 C1 10 E8 ?? ?? ?? ?? 83 78"
addr = AddressManager(_storage.data, _logger).get("addr", scan_pattern, sig)
_storage.save()

_ver_storage = _storage.data[FFxiv_Version]

_code = read_memory(
    StructFactory.OffsetStruct({
        "mark1": (c_ubyte * 2, 0),
        "mark2": (c_ubyte * 2, 0x1b)
    }), addr)


def is_patched():
    return _code.mark1[:] == [0x90, 0x90]
Пример #27
0
from ctypes import *
from datetime import datetime
from typing import Optional

from FFxivPythonTrigger.Logger import Logger
from FFxivPythonTrigger.memory.StructFactory import OffsetStruct

from ..Structs import RecvNetworkEventBase

_logger = Logger("XivNetwork/ProcessActorCast")

ServerActorCast = OffsetStruct({
    'action_id': c_ushort,
    'skill_type': c_ubyte,
    'unk0': c_ubyte,
    'unk1': c_uint,
    'cast_time': c_float,
    'target_id': c_uint,
    'rotation': c_float,
    'unk2': c_uint,
    'x': c_ushort,
    'y': c_ushort,
    'z': c_ushort,
    'unk3': c_ushort,
})

size = sizeof(ServerActorCast)
_logger.debug("size: %d" % size)


class RecvActorCastEvent(RecvNetworkEventBase):
Пример #28
0
from ctypes import *

from FFxivPythonTrigger.Logger import Logger
from FFxivPythonTrigger.memory.StructFactory import OffsetStruct
from ..Structs import SendNetworkEventBase

ClientEventStart = OffsetStruct(
    {
        'target_id': c_uint,
        'unk0': c_uint,
        'event_id': c_ushort,
        'category': c_ushort,
        'unk3': c_uint,
    }, 16)

_logger = Logger("XivNetwork/ProcessClientEventStart")
size = sizeof(ClientEventStart)


class ClientEventStartEvent(SendNetworkEventBase):
    id = "network/send_event_start"
    name = "network send event start"

    def text(self):
        return f"event start {self.raw_msg.category}-{self.raw_msg.event_id} (target:{hex(self.raw_msg.target_id)})"


def get_event(msg_time, header, raw_msg):
    if len(raw_msg) < size:
        _logger.warning("message is too short to parse:[%s]" % raw_msg.hex())
        return
Пример #29
0
class ClientTrigger(
        OffsetStruct(
            {
                'param1': c_uint,
                'param2': c_uint,
                'param3': c_uint,
                'param4': c_uint,
                'param5': c_uint,
                'param6': c_uint,
                'param7': c_uint,
                'param8': c_uint,
            }, 32)):
    pass


_logger = Logger("XivNetwork/ProcessClientTrigger")
size = sizeof(ClientTrigger)


class ClientTriggerEvent(SendNetworkEventBase):
    id = "network/send_client_trigger"
    name = "network send client trigger"

    def text(self):
        return '|'.join(hex(v)[2:] for v in self.raw_msg.get_data().values())


def get_event(msg_time, header, raw_msg):
    if len(raw_msg) < size:
        _logger.warning("message is too short to parse:[%s]" % raw_msg.hex())
        return
Пример #30
0
from ctypes import sizeof
from threading import Lock
from traceback import format_exc
from typing import Optional
from zlib import decompress, MAX_WBITS
from socket import ntohl
from datetime import datetime, timedelta, timezone

from FFxivPythonTrigger.Logger import Logger

from .Structs import FFXIVBundleHeader

_logger = Logger("XivNetwork/BundleDecoder")

MAGIC_NUMBER = bytearray(b"\x52\x52\xa0\x41")

_encoding_error = False

invalid_headers = set()

min_datetime = datetime(1970, 1,
                        1).replace(tzinfo=timezone.utc).astimezone(tz=None)


def ntohll(host):
    return ntohl(host & 0xFFFFFFFF) << 32 | ntohl((host >> 32) & 0xFFFFFFFF)


header_size = sizeof(FFXIVBundleHeader)