Private Chat Logging


#1

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

#2

can we add here stallchat too?


#3

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__)

#4

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


#5

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


#6

alright than thanks for help :slight_smile:


#7

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:


#8
  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.