Private Chat Logging

This plugin will log all private chat messages to a file. It only supports 15.4.7+.

from phBot import *
import QtBind
import struct
import time
import json

server = None
name = None
encoding = None
log_chat = False
in_game = False
config_path = get_config_dir() + 'PrivateChatLogging.json'

gui = QtBind.init(__name__, 'Private Chat Logging')
checkbox1 = QtBind.createCheckBox(gui, 'enable_logging', 'Enable logging', 10, 10)

log('[Private Chat Logging] Loaded')

def enable_logging(state):

    # Only attempt to save if the player is in game
    if in_game:

        global log_chat
        log_chat = state

        with open(config_path, 'r+', encoding='utf-8') as f:

            # Read the JSON
            try:
                data = json.load(f)
            except:
                data = {}

            if not server in data:
                data[server] = {}

            # Save the setting
            data[server][name] = log_chat

            # Overwrite
            f.seek(0)
            json.dump(data, f)
            f.truncate()

def parse_server_chat(data):

    if log_chat:

        # Packet index
        index = 0

        # Chat type
        t = struct.unpack_from('<B', data, index)[0]
        index += 1

        # Private
        if t == 2:

            # Player name length
            length = struct.unpack_from('<H', data, index)[0]
            index += 2

            # Player name
            player_name = struct.unpack_from('<' + str(length) + 's', data, index)[0].decode('cp1252')
            index += length

            # Length of message
            length = struct.unpack_from('<H', data, index)[0]
            index += 2

            # Message
            message = struct.unpack_from('<' + str(length * (2 if encoding == 'utf-16le' else 1)) + 's', data, index)[0].decode(encoding)

            # Save the message
            with open(get_log_dir() + '%s_%s_chat.log' % (server, name), 'a', encoding='utf-8') as f:
                f.write('[%s] %s (Private): %s\n' % (time.strftime('%H:%M:%S'), player_name, message))

def joined_game():

    data = get_character_data()

    global server, name, encoding, log_chat, in_game

    in_game = True
    server = data['server']
    name = data['name']
    encoding = get_encoding()
    log_chat = False

    with open(config_path, 'r', encoding='utf-8') as f:   

        # Read the JSON
        try:
            data = json.load(f)
        except:
            data = {}

        # Make sure the setting is in the file
        if server in data and name in data[server]:
            log_chat = data[server][name]

    QtBind.setChecked(gui, checkbox1, log_chat)

def handle_joymax(opcode, data):

    if opcode == 0x3026:
        parse_server_chat(data)

    return True
5 Likes

can we add here stallchat too?

Maybe this helps. Simple Chatlogging into Log/SERVERNAME_CHARNAME_ChatLog.txt

from phBot import *
import phBotChat
import datetime

def handle_chat(t,player,msg):
	type = 'None'
	if t == 2:
		type = '(Private)'
	if t == 9:
		type = '(Stall)'
	if type != 'None':
		file = open("Log/"+get_character_data()['server']+"_"+get_character_data()['name']+"_ChatLog.txt","a")
		date = datetime.datetime.now().strftime("%d-%m-%Y %H:%M:%S")
		file.write('['+date+']'+type+player+': '+msg+'\n')
		file.close()
		
log('[%s] Loaded' % __name__)
1 Like

this save private and stall chat both? thx for help :slight_smile: me make it copy paste enough? cuz first plugin seems long

The one I wrote does manual parsing and was created before I simplified it. The new one by @Delirus logs private and stall.

alright than thanks for help :slight_smile:

1 Like

Could you clarify how this new method handle_chat works? @Ryan
Like for example:

  • What means every number t type ? Chat api have 8 types, I’m missing one?
  • The only time that player is None could be because server notice?
  • What happen at private messages specifically? If a message is sent to some player, this will pass on this function? at that case player is empty or it’s me?

Because I’m trying to show messages like chat but probably I’ll need to save the destinatary/receiver … :thinking:

  1. t is the type sent by the server. This handle_chat function simply parses the chat messages and sends it off to Python so it’s simpler.
  2. It’s only None if it’s a server notice.
  3. You will not receive messages sent by the game client or by the bot. Only received messages.
1 Like

Can you give us a list of all type numbers with his meaning? (like get_locale())
I read before something about event messages, it’s maybe a new type or it’s included at server notice?

I can but it’s not that helpful because some servers set it to 0 or a random value to stop bots.

Awesome plugin thanks. I want to log the party and guild messages, how can I do that?

take this one and edit as you wish

All = 1,
PM = 2,
AllGM = 3,
Party = 4,
Guild = 5, 
Global = 6,
Notice = 7,
Stall = 9, 
Union = 11,
NPC = 13,
Accademy = 16,

@ahmetberkay thanks its worked.

1 Like

you mean when relogin … PM’s dont get deleted?
or do i have to manually check a certain .txt file for its PM logs?

It’s saved to a text file in the Log folder.

how can i make Log all chats with its types