mirror of
https://git.ugnet.gay/CrossTalk/azul.git
synced 2026-05-27 22:59:49 +00:00
production init
This commit is contained in:
@@ -0,0 +1,223 @@
|
||||
from typing import Tuple, Any, Iterable, List
|
||||
from enum import IntEnum
|
||||
|
||||
from util.misc import DefaultDict, MultiDict, arbitrary_encode
|
||||
|
||||
from core.backend import BackendSession
|
||||
from core.models import Substatus
|
||||
|
||||
import settings
|
||||
|
||||
class YMSGService(IntEnum):
|
||||
LogOn = 0x01
|
||||
LogOff = 0x02
|
||||
IsAway = 0x03
|
||||
IsBack = 0x04
|
||||
Message = 0x06
|
||||
IDActivate = 0x07
|
||||
IDDeactivate = 0x08
|
||||
UserStat = 0x0A
|
||||
ContactNew = 0x0F
|
||||
AddIgnore = 0x11
|
||||
PingConfiguration = 0x12
|
||||
SystemMessage = 0x14
|
||||
SkinName = 0x15
|
||||
ClientHostStats = 0x16
|
||||
MassMessage = 0x17
|
||||
ConfInvite = 0x18
|
||||
ConfLogon = 0x19
|
||||
ConfDecline = 0x1A
|
||||
ConfLogoff = 0x1B
|
||||
ConfAddInvite = 0x1C
|
||||
ConfMsg = 0x1D
|
||||
MessageV2 = 0x27
|
||||
AvatarOld = 0xBD
|
||||
Avatar = 0xC7
|
||||
FileTransfer = 0x46
|
||||
VoiceChat = 0x4A
|
||||
Notify = 0x4B
|
||||
Handshake = 0x4C
|
||||
P2PFileXfer = 0x4D
|
||||
P2PFileXfer8 = 0xDC
|
||||
P2PPhotoSharing = 0xD2
|
||||
PeerToPeer = 0x4F
|
||||
VideoChat = 0x50
|
||||
AuthResp = 0x54
|
||||
List = 0x55
|
||||
Auth = 0x57
|
||||
FriendAdd = 0x83
|
||||
FriendRemove = 0x84
|
||||
Ignore = 0x85
|
||||
ContactDeny = 0x86
|
||||
GroupRename = 0x89
|
||||
Ping = 0x8A
|
||||
ChatJoin = 0x96
|
||||
IsInvisible = 0xC5
|
||||
StatusUpdate = 0xC6
|
||||
StatusUpdate2 = 0xF0
|
||||
# `static var YES_CHAT_PING = 161;` 161 = 0xA1
|
||||
# Yahoo! Messenger 9.0's `desktopHub` SWF seems to list a lot of YMSG service codes and field defs in its code. :p
|
||||
ChatPing = 0xA1
|
||||
ChatSession = 0xD4
|
||||
ContactRegroup = 0xE7
|
||||
# Documented by the Yahsmosis project (https://www.autoitscript.com/forum/topic/142448-help-with-yahomosis/) - this appears to be used when a protocol-level error occurs (protocol version "cloaking", bad `Y`/`T` cookies, invalid Yahoo ID, invalid key/value pairs, etc.). Unsure what protocol version this was first placed into or how far back in the protocol version Yahoo's servers decided to send this on (A Wireshark capture indicates as far back as YMSG12)
|
||||
ProtocolError = 0x07D1
|
||||
|
||||
class YMSGStatus(IntEnum):
|
||||
# Available/Client Request
|
||||
Available = 0x00000000
|
||||
# BRB/Server Response
|
||||
BRB = 0x00000001
|
||||
Busy = 0x00000002
|
||||
# "Not at Home"/BadUsername
|
||||
NotAtHome = 0x00000003
|
||||
NotAtDesk = 0x00000004
|
||||
# "Not in Office"/OfflineMessage/MultiPacket
|
||||
NotInOffice = 0x00000005
|
||||
OnPhone = 0x00000006
|
||||
OnVacation = 0x00000007
|
||||
OutToLunch = 0x00000008
|
||||
SteppedOut = 0x00000009
|
||||
# Dunno when this is used, but the `PeerToPeer` service sends this according to Pidgin
|
||||
P2P = 0x0000000B
|
||||
Invisible = 0x0000000C
|
||||
Bad = 0x0000000D
|
||||
Locked = 0x0000000E
|
||||
Typing = 0x00000016
|
||||
Custom = 0x00000063
|
||||
Idle = 0x000003E7
|
||||
WebLogin = 0x5A55AA55
|
||||
Offline = 0x5A55AA56
|
||||
LoginError = 0xFFFFFFFF
|
||||
|
||||
@classmethod
|
||||
def ToSubstatus(cls, ymsg_status: 'YMSGStatus') -> Substatus:
|
||||
return _ToSubstatus[ymsg_status]
|
||||
|
||||
@classmethod
|
||||
def FromSubstatus(cls, substatus: Substatus) -> 'YMSGStatus':
|
||||
return _FromSubstatus[substatus]
|
||||
|
||||
_ToSubstatus = DefaultDict(Substatus.Busy, {
|
||||
YMSGStatus.Offline: Substatus.Offline,
|
||||
YMSGStatus.Available: Substatus.Online,
|
||||
YMSGStatus.BRB: Substatus.BRB,
|
||||
YMSGStatus.Busy: Substatus.Busy,
|
||||
YMSGStatus.Idle: Substatus.Idle,
|
||||
YMSGStatus.Invisible: Substatus.Invisible,
|
||||
YMSGStatus.NotAtHome: Substatus.NotAtHome,
|
||||
YMSGStatus.NotAtDesk: Substatus.NotAtDesk,
|
||||
YMSGStatus.NotInOffice: Substatus.NotInOffice,
|
||||
YMSGStatus.OnPhone: Substatus.OnPhone,
|
||||
YMSGStatus.OutToLunch: Substatus.OutToLunch,
|
||||
YMSGStatus.SteppedOut: Substatus.SteppedOut,
|
||||
YMSGStatus.OnVacation: Substatus.OnVacation,
|
||||
YMSGStatus.Locked: Substatus.Away,
|
||||
YMSGStatus.LoginError: Substatus.Offline,
|
||||
YMSGStatus.Bad: Substatus.Offline,
|
||||
})
|
||||
_FromSubstatus = DefaultDict(YMSGStatus.Bad, {
|
||||
Substatus.Offline: YMSGStatus.Offline,
|
||||
Substatus.Online: YMSGStatus.Available,
|
||||
Substatus.Busy: YMSGStatus.Busy,
|
||||
Substatus.Idle: YMSGStatus.Idle,
|
||||
Substatus.BRB: YMSGStatus.BRB,
|
||||
Substatus.Away: YMSGStatus.NotAtHome,
|
||||
Substatus.OnPhone: YMSGStatus.OnPhone,
|
||||
Substatus.OutToLunch: YMSGStatus.OutToLunch,
|
||||
Substatus.Invisible: YMSGStatus.Invisible,
|
||||
Substatus.NotAtHome: YMSGStatus.NotAtHome,
|
||||
Substatus.NotAtDesk: YMSGStatus.NotAtDesk,
|
||||
Substatus.NotInOffice: YMSGStatus.NotInOffice,
|
||||
Substatus.OnVacation: YMSGStatus.OnVacation,
|
||||
Substatus.SteppedOut: YMSGStatus.SteppedOut,
|
||||
})
|
||||
|
||||
KVSType = MultiDict[bytes, bytes]
|
||||
EncodedYMSG = Tuple[YMSGService, YMSGStatus, KVSType]
|
||||
|
||||
def build_p2p_msg_packet(bs: BackendSession, sess_id: int, p2p_dict: KVSType) -> Iterable[EncodedYMSG]:
|
||||
user_to = bs.user
|
||||
|
||||
p2p_conn_dict = MultiDict([
|
||||
(b'4', p2p_dict.get(b'4') or b''),
|
||||
(b'5', arbitrary_encode(user_to.username)),
|
||||
])
|
||||
|
||||
#p2p_conn_dict.add(b'11', binascii.hexlify(struct.pack('!I', sess_id)).decode().upper().encode('utf-8'))
|
||||
p2p_conn_dict.add(b'11', b'0')
|
||||
if p2p_dict.get(b'12') is not None: p2p_conn_dict.add(b'12', p2p_dict.get(b'12') or b'')
|
||||
if p2p_dict.get(b'13') is not None: p2p_conn_dict.add(b'13', p2p_dict.get(b'13') or b'')
|
||||
p2p_conn_dict.add(b'49', p2p_dict.get(b'49') or b'')
|
||||
if p2p_dict.get(b'61') is not None: p2p_conn_dict.add(b'61', p2p_dict.get(b'61') or b'')
|
||||
|
||||
yield (YMSGService.PeerToPeer, YMSGStatus.BRB, p2p_conn_dict)
|
||||
|
||||
def build_ft_packet(bs: BackendSession, sess_id: int, xfer_dict: KVSType) -> Iterable[EncodedYMSG]:
|
||||
user_to = bs.user
|
||||
|
||||
ft_dict = MultiDict([
|
||||
(b'5', arbitrary_encode(user_to.username)),
|
||||
(b'4', xfer_dict.get(b'1') or xfer_dict.get(b'4') or b'')
|
||||
])
|
||||
|
||||
ft_type = xfer_dict.get(b'13')
|
||||
if ft_type is not None: ft_dict.add(b'13', ft_type)
|
||||
if ft_type == b'1':
|
||||
if xfer_dict.get(b'27') is not None: ft_dict.add(b'27', xfer_dict.get(b'27') or b'')
|
||||
if xfer_dict.get(b'28') is not None: ft_dict.add(b'28', xfer_dict.get(b'28') or b'')
|
||||
|
||||
if xfer_dict.get(b'20') is not None: ft_dict.add(b'20', xfer_dict.get(b'20') or b'')
|
||||
if xfer_dict.get(b'53') is not None: ft_dict.add(b'53', xfer_dict.get(b'53') or b'')
|
||||
if xfer_dict.get(b'14') is not None: ft_dict.add(b'14', xfer_dict.get(b'14') or b'')
|
||||
if xfer_dict.get(b'54') is not None: ft_dict.add(b'54', xfer_dict.get(b'54') or b'')
|
||||
if ft_type in (b'2',b'3'):
|
||||
# For shared files
|
||||
if xfer_dict.get(b'27') is not None: ft_dict.add(b'27', xfer_dict.get(b'27') or b'')
|
||||
if xfer_dict.get(b'53') is not None: ft_dict.add(b'53', xfer_dict.get(b'53') or b'')
|
||||
|
||||
# For P2P messaging
|
||||
if xfer_dict.get(b'2') is not None: ft_dict.add(b'2', xfer_dict.get(b'2') or b'')
|
||||
if xfer_dict.get(b'11') is not None:
|
||||
#ft_dict.add(b'11', binascii.hexlify(struct.pack('!I', sess_id)).decode().upper().encode('utf-8'))
|
||||
ft_dict.add(b'11', b'0')
|
||||
if xfer_dict.get(b'12') is not None: ft_dict.add(b'12', xfer_dict.get(b'12') or b'')
|
||||
if xfer_dict.get(b'60') is not None: ft_dict.add(b'60', xfer_dict.get(b'60') or b'')
|
||||
if xfer_dict.get(b'61') is not None: ft_dict.add(b'61', xfer_dict.get(b'61') or b'')
|
||||
if ft_type == b'5':
|
||||
if xfer_dict.get(b'54') is not None: ft_dict.add(b'54', xfer_dict.get(b'54') or b'')
|
||||
if ft_type == b'6':
|
||||
if xfer_dict.get(b'20') is not None: ft_dict.add(b'20', xfer_dict.get(b'20') or b'')
|
||||
if xfer_dict.get(b'53') is not None: ft_dict.add(b'53', xfer_dict.get(b'53') or b'')
|
||||
if xfer_dict.get(b'54') is not None: ft_dict.add(b'54', xfer_dict.get(b'54') or b'')
|
||||
if ft_type == b'9':
|
||||
if xfer_dict.get(b'53') is not None: ft_dict.add(b'53', xfer_dict.get(b'53') or b'')
|
||||
if xfer_dict.get(b'49') is not None: ft_dict.add(b'49', xfer_dict.get(b'49') or b'')
|
||||
|
||||
yield (YMSGService.P2PFileXfer, YMSGStatus.BRB, ft_dict)
|
||||
|
||||
def build_http_ft_packet(bs: BackendSession, sender: str, url_path: str, upload_time: float, message: str) -> Iterable[Any]:
|
||||
user = bs.user
|
||||
|
||||
yield (YMSGService.FileTransfer, YMSGStatus.BRB, MultiDict([
|
||||
(b'1', arbitrary_encode(user.username)),
|
||||
(b'5', arbitrary_encode(sender)),
|
||||
(b'4', arbitrary_encode(user.username)),
|
||||
(b'14', arbitrary_encode(message)),
|
||||
(b'38', str(upload_time + 86400).encode('utf-8')),
|
||||
(b'20', arbitrary_encode('http://{}{}'.format(settings.USERSTORAGE_HOST, url_path))),
|
||||
]))
|
||||
|
||||
def split_to_chunks(s: str, count: int) -> List[str]:
|
||||
i = 0
|
||||
j = 0
|
||||
final = []
|
||||
|
||||
while i < len(s):
|
||||
j += count
|
||||
if j > len(s):
|
||||
j = len(s)
|
||||
final.append(s[i:j])
|
||||
i += count
|
||||
|
||||
return final
|
||||
Reference in New Issue
Block a user