mp-pinheiro/FairFruit-Bot

Request for adaptation

Closed this issue · 5 comments

Could you add the missing commands for n64 and adapt the script to receive messages via discord or telegram (or something universal)? Unfortunately, I'm not very good at coding (especially when it's not just python), so it would be much appreciated.

hey!

missing commands is pretty easy, just make your config.json something like this:

{
    "controls": {
        "up": "A Up",
        "down": "A Down",
        "left": "A Left",
        "right": "A Right",
        "a": "A",
        "b": "B",
        "z": "Z",
        "q": "C Down",
        "w": "C Left",
        "e": "C Right",
        "r": "C Up",
        "t": "DPad D",
        "y": "DPad L",
        "u": "DPad R",
        "i": "DPad U",
        "o": "L",
        "p": "R",
        "h": "Start"
    },
    "options": {
        "delay": 0.1,
        "max": 1000
    }
}

didnt test this but should work. if not, its just a matter of mapping the keyboard key you want on the left to an n64 button on the right using the names on the n64 bizhawk table.

and add the new keys to your config.lua:

{
    "Up": {
        "inputTime": "config.analogTime",
        "threshold": "config.analogThreshold"
    },
    "Down": {
        "inputTime": "config.analogTime",
        "threshold": "config.analogThreshold"
    },
    "Left": {
        "inputTime": "config.analogTime",
        "threshold": "config.analogThreshold"
    },
    "Right": {
        "inputTime": "config.analogTime",
        "threshold": "config.analogThreshold"
    },
    "A": {
        "inputTime": "config.keyTime",
        "threshold": "config.keyThreshold"
    },
    "B": {
        "inputTime": "config.keyTime",
        "threshold": "config.keyThreshold"
    },
    "Z": {
        "inputTime": "config.keyTime",
        "threshold": "config.keyThreshold"
    },
    "C Down": {
        "inputTime": "config.keyTime",
        "threshold": "config.keyThreshold"
    },
    "C Left": {
        "inputTime": "config.keyTime",
        "threshold": "config.keyThreshold"
    },
    "C Right": {
        "inputTime": "config.keyTime",
        "threshold": "config.keyThreshold"
    },
    "C Up": {
        "inputTime": "config.keyTime",
        "threshold": "config.keyThreshold"
    },
    "DPad D": {
        "inputTime": "config.keyTime",
        "threshold": "config.keyThreshold"
    },
    "DPad L": {
        "inputTime": "config.keyTime",
        "threshold": "config.keyThreshold"
    },
    "DPad R": {
        "inputTime": "config.keyTime",
        "threshold": "config.keyThreshold"
    },
    "DPad U": {
        "inputTime": "config.keyTime",
        "threshold": "config.keyThreshold"
    },
    "L": {
        "inputTime": "config.keyTime",
        "threshold": "config.keyThreshold"
    },
    "R": {
        "inputTime": "config.keyTime",
        "threshold": "config.keyThreshold"
    },
    "Start": {
        "inputTime": "config.keyTime",
        "threshold": "config.keyThreshold"
    }
}

now for adding support for Telegram or Discord, that'd be a lot more work. you'd need to replace the twtch bot with a telegram or discord bot, and completely reimplement the logic of fetching keys from them and possibly sending them over to bizhawk via sockets.

if you're not experienced with coding, that can be quite challenging. i'd recommend start with playing around with a simpler discord or telegram bot first, there are some good videos on youtube about that. also, you'll need to understand sockets to reimplement the bot/emulator communication.

Thank you for your help with the missing commands! I understand correctly that I only need to change 3 python files + env to adapt?

do you mean to adpat for discord or telegram?

if so, you'll need to adapt mainly bot.py, replace the twitch bot part with the discord/telegram bot, and correctly integrate the communicator module that handles the socket communication logic with bizhawk

basically this part:

FairFruit-Bot/bot.py

Lines 44 to 91 in 6f9cd83

class Bot(Keyword):
filename = 'config.json'
try:
cfg = load_json(filename)
except FileNotFoundError:
cfg = write_json(filename)
communicator = None
def __init__(self, gamemode):
super().__init__()
self._gamemode = gamemode
Bot.communicator = []
Bot.communicator.append(Communicator())
if gamemode == "double":
Bot.communicator.append(Communicator(doubleSetup=True))
self._set_command_handler()
def _get_comm_index_by_name(self, name):
letter = name[0].lower()
return 1 if letter >= "m" else 0
def _set_command_handler(self):
async def handler_function(message):
"""Handles keystroke commands from twitch chat."""
# Skip prefix character
content = message.content[1:]
author = message.author.name
args = content.split()
controls = Bot.cfg['controls']
options = Bot.cfg['options']
delay = float(options['delay'])
index = 0
if self._gamemode == "double":
index = self._get_comm_index_by_name(author)
communicator = Bot.communicator[index]
word = args[0]
if word in controls:
key = author + ":" + controls[word] + ";"
communicator.send_data(key)
# Wait delay amount of seconds
await asyncio.sleep(delay)
self.prefix_keywords = {"!": handler_function}

you'll have to replace it with a telegram/discord bot in a similar fashion. it needs to:

  1. load the config.json file to fetch the correct keys and mappings to send to bizzhawk
  2. setup the communicator(s) (one if youre doing just 1 emulator, 2 if youre doing double mode)
  3. setup the command handler. that's the logic that should run every time a command is detected in discord/telegram:

    FairFruit-Bot/bot.py

    Lines 66 to 91 in 6f9cd83

    def _set_command_handler(self):
    async def handler_function(message):
    """Handles keystroke commands from twitch chat."""
    # Skip prefix character
    content = message.content[1:]
    author = message.author.name
    args = content.split()
    controls = Bot.cfg['controls']
    options = Bot.cfg['options']
    delay = float(options['delay'])
    index = 0
    if self._gamemode == "double":
    index = self._get_comm_index_by_name(author)
    communicator = Bot.communicator[index]
    word = args[0]
    if word in controls:
    key = author + ":" + controls[word] + ";"
    communicator.send_data(key)
    # Wait delay amount of seconds
    await asyncio.sleep(delay)
    self.prefix_keywords = {"!": handler_function}
    1. fetch the msg sent and check if its a command (ie: !a)
    2. fetch the bizhawk key mapped to that command on config.json
    3. build the socket message to send to bizhawk (looks like key = author + ":" + controls[word] + ";", ie: fairfruit:Z)
    4. send the socket message via communicator
    5. wait the determined delay

That's awesome thanks so much for the explanation ❤️