code_func.py
"""
import os
import time

from functions.hardwired_functions import *
from functions.init_player import *
from functions.deconnect_player import *
from functions.troops_functions import *
from functions.player_id_functions import *
from functions.player_functions import *
from functions.files_functions import *
from functions.other_functions import *

from triggers.on_connect import *
from triggers.on_deconnect import *


def main_code(unique_id, event, nr_args, args):
    event = args[0]
    
    if unique_id == 0 and event != 1 and event != 2:
        return send_data_to_player(unique_id, [2, 0])  # force log in
    else:
        if event == 1:
            # REGISTER ACCOUNT
            # INPUT: arg1-username arg2-password
            # OUTPUT: arg1-state arg2-unique id
            if len(args) > 1:
                username = args[1]
                if check_string(username) and not username.isnumeric():
                    if os.path.exists("accounts/" + username + ".txt"):
                        return send_data_to_player(unique_id, [1, 0])  # the account already exists
                    else:
                        last_unique_id = read_file("server_vars/player.txt") + 1
                        write_file("server_vars/player.txt", last_unique_id)

                        write_file("username_id/" + username + ".txt", last_unique_id)
                        write_file("accounts/" + username + ".txt", "")

                        make_dir('players/' + str(last_unique_id) + '/')  # create the id directory
                        init_player(last_unique_id, username)

                        return send_data_to_player(unique_id, [1, 1, last_unique_id])  # successful creation of account
                else:
                    return send_data_to_player(unique_id, [1, 4])  # invalid characters used
        elif event == 2:
            # LOG IN
            # INPUT: arg1-username arg2-password
            # OUTPUT: arg1-state arg2-unique id arg3-local id
            if len(args) > 1:
                username = args[1]
                if check_string(username) and not username.isnumeric():
                    if os.path.exists("accounts/" + username + ".txt"):

                        local_id_slot = find_local_id(0)
                        if local_id_slot != 0:
                            if os.path.exists("ip_login/" + get_player_ip() + ".txt"):
                                unique_id_real = get_unique_id_by_username(username)
                                return send_data_to_player(unique_id, [2, 2, unique_id_real, get_local_id_by_ip()])  # successful log in
                                send_initial_players(unique_id_real)
                            else:
                                unique_id_real = get_unique_id_by_username(username)
                                write_file("ip_login/" + get_player_ip() + ".txt", local_id_slot)
                                write_file("local_id/" + str(local_id_slot) + ".txt", unique_id_real)
                                write_file("players/" + str(unique_id_real) + "/active.txt", 1)
                                write_file("players/" + str(unique_id_real) + "/last_time_active.txt", time.time())
                                write_file("players/" + str(unique_id_real) + "/ip.txt", get_player_ip())
                                write_file("players/" + str(unique_id_real) + "/local_id.txt", local_id_slot)
                                write_file("players/" + str(unique_id_real) + "/ping.txt", 0)
                                write_file("players/" + str(unique_id_real) + "/ping_var.txt", 0)
                                return send_data_to_player(unique_id, [2, 2, unique_id_real, local_id_slot])  # successful log in
                                send_initial_players(unique_id)
                                ti_on_player_connect(unique_id_real)
                        else:
                            return send_data_to_player(unique_id, [2, 3])  # the server is full
                    else:
                        return send_data_to_player(unique_id, [2, 1])  # invalid user or pass
                else:
                    return send_data_to_player(unique_id, [2, 1])  # invalid user or pass
            else:
                return send_data_to_player(unique_id, [2, 4])  # invalid characters used

        # Remaining conditions to be implemented similarly
        elif event == 3:
            # CHAT
            # Input arg1 - message
            if len(args) > 1:
                message = args[1]
                if message != '':
                    if message.isnumeric():
                        message += ' '
                    username = get_player_username(unique_id)
                    for i in range(1, 11):
                        u_id = get_unique_id_by_local(i)
                        if u_id != 0:
                            return send_data_to_player(u_id, [3, message, username], 2)

        elif event == 4:
            # SAVE PLAYER POSITION
            # Input: arg1-x arg2-y arg3-rotation
            # output: none
            if len(args) > 3:
                x, y, rot = args[1], args[2], args[3]
                allow_teleport = False # Define allow_teleport if not already defined
                if allow_teleport:
                    set_position(unique_id, x, y, rot)
                else:
                    position = get_position(unique_id)
                    old_x, old_y, old_rot = position[0], position[1], position[2]
                    distance = ((old_x - x) ** 2 + (old_y - y) ** 2) ** 0.5
                    if distance < 1000:
                        set_position(unique_id, x, y, rot)
                    else:
                        to_send = [5, old_x, old_y, old_rot]
                        return send_data_to_player(unique_id, to_send)
                        # return send_data_to_player(unique_id, [15, " " + distance, 0xFF0000], 1)

        # Implement the remaining conditions using the same structure
        elif event == 6:
            # SEND PLAYERS POSITION
            # Input: none
            # Output: arg1 - number of players arg2 - local player id arg3 - x arg4- y arg5 - rot arg6 -local player id ....
            number_of_players = 0
            to_send = [6]
            c = 2
            for i in range(1, 11):
                u_id = get_unique_id_by_local(i)
                if u_id != 0 and u_id != unique_id:
                    number_of_players += 1
                    to_send[c] = i
                    c += 1

                    position = get_position(u_id)
                    x, y, rot = position[0], position[1], position[2]

                    to_send[c] = x
                    c += 1
                    to_send[c] = y
                    c += 1
                    to_send[c] = rot
                    c += 1
            c -= 1
            to_send[1] = number_of_players

            return send_data_to_player(unique_id, to_send)

        elif event == 9:
            # PING
            if len(args) > 1:
                if args[1] == 0:
                    write_file("players/" + str(unique_id) + "/ping_var.txt", round(time.time(), 2))
                    return send_data_to_player(unique_id, [9, 1])
                else:
                    time_var = read_file("players/" + str(unique_id) + "/ping_var.txt")
                    ping = round((time.time() - time_var) * 100)
                    write_file("players/" + str(unique_id) + "/ping.txt", ping)
                    write_file("players/" + str(unique_id) + "/ping_var.txt", 0)
                    
                    data = [9, 0]
                    for i in range(1, 11):
                        u_id = get_unique_id_by_local(i)
                        if u_id != 0:
                            data.append(read_file("players/" + str(u_id) + "/ping.txt") if u_id != 0 else 0)
                    
                    return send_data_to_player(unique_id, data)

        elif event == 10:
            # SEND PLAYER INVENTORY
            inv = read_file("players/" + str(unique_id) + "/inventory.txt")
            inv = inv.split("|")
            inv[0] = 10
            return send_data_to_player(unique_id, inv)

        elif event == 11:
            # SEND PLAYER GOLD
            return send_data_to_player(unique_id, [11, get_gold(unique_id)])

        elif event == 14:
            # SEND PLAYER TROOPS
            troops = read_file("players/" + str(unique_id) + "/troops.txt")
            troops = troops.split("|")
            nr = sum([1 for a in troops if a != -1])
            troops[0] = 14
            troops[1] = nr + 2  # incrementing here, so we will not have to increment in the game
            return send_data_to_player(unique_id, troops)

        elif event == 16:
            # JOIN BATTLE
            # New event for setting up or acknowledging a meeting
            # INPUT: arg1 - multiplayer party name
            if len(args) > 1:
                multiplayer_party_name = args[1]
                target_player_unique_id = get_unique_id_by_username(multiplayer_party_name)

                # Perform checks and actions as needed…
                return send_data_to_player(target_player_unique_id, [16, 0])  # Example action

                # Additional handling, like updating status, logging, etc.



"""

multiplayer.py
"""
from flask import Flask, request, make_response
import os
from time import time
from server_config import *  # 

from code_func import main_code
from functions.hardwired_functions import *
from functions.init_player import *
from functions.deconnect_player import *
from functions.troops_functions import *
from functions.player_id_functions import *
from functions.player_functions import *
from functions.files_functions import *
from functions.other_functions import *


from triggers.on_connect import *
from triggers.on_deconnect import *


app = Flask(__name__)


@app.route('/multiplayer')
def main():
    counter = 1
    result = None  # Initialized result to None or an appropriate default value

    # Checking for active players
    last_time_check = read_file("server_vars/check_time.txt")
    if (time() - float(last_time_check)) >= 1:
        write_file("server_vars/check_time.txt", time())
        check_players_activity()
    
    player_ip = get_player_ip()
    if os.path.exists(f"ip_login/{player_ip}.txt"):
        local_id = read_file(f"ip_login/{player_ip}.txt")
        unique_id = read_file(f"local_id/{local_id}.txt")
    else:
        unique_id = None

    # Handle events and arguments
    while True:
        event = request.args.get(f"event{counter}")
        if event:
            number_of_arguments = request.args.get(f"nrarg{counter}", default=0, type=int)
            data_args = [event]
            for i in range(1, number_of_arguments):
                arg = request.args.get(f"arg{counter}|{i}")
                if arg:
                    data_args.append(arg)
            # Ensure result is assigned a new value or modified during each loop iteration as needed
            result = main_code(unique_id, event, number_of_arguments - 1, data_args)
            counter += 1
        else:
            break

    # Check if result is still None (or whatever default value you chose) and handle accordingly
    if result is None:
        result = "No event processed"  # Adjust this based on the needs of your application

    return str(result)


if __name__ == '__main__':
    app.run(debug=True)
"""

server_config.py
"""
dev_log = 1  # it holds all the data (every single packet). it is for devs or for errors reporting. 1 - enable, 0 - disable
dev_log_path = 'logs/dev_log.txt'

server_log = 1  # enable log save
server_log_path = 'logs/server_log.txt'

allow_teleport = 1  # 1 - allow teleport on the map; 0 - does not allow. If set to 0, it is possible to crash the game when you try to teleport.

starting_gold = 2000
"""


functions/check_players_activity.py
"""
import os
import time

from functions.hardwired_functions import *
from functions.init_player import *
from functions.deconnect_player import *
from functions.troops_functions import *
from functions.player_id_functions import *
from functions.player_functions import *
from functions.files_functions import *
from functions.other_functions import *


def read_file(file_path):
    if os.path.exists(file_path):
        with open(file_path, 'r') as file:
            return file.read()
    return 0


def check_players_activity():
    for i in range(1, 11):
        unique_id = read_file(f"local_id/{i}.txt")
        if unique_id != 0:
            last_time_active = int(read_file(f"players/{unique_id}/last_time_active.txt"))
            if time.time() - last_time_active > 3:  # if more than 3 seconds passed since last active
                deconnect_player(unique_id)

"""


functions/deconnect_player.py
"""
import os
from functions.hardwired_functions import *
from functions.init_player import *
from functions.deconnect_player import *
from functions.troops_functions import *
from functions.player_id_functions import *
from functions.player_functions import *
from functions.files_functions import *
from functions.other_functions import *

from triggers.on_connect import *
from triggers.on_deconnect import *

def deconnect_player(unique_id):
    player_ip = read_file(f"players/{unique_id}/ip.txt")
    local_id = get_local_id_by_unique(unique_id)
    
    if os.path.exists(f"ip_login/{player_ip}.txt"):
        os.remove(f"ip_login/{player_ip}.txt")
    
    write_file(f"local_id/{get_local_id_by_unique(unique_id)}.txt", 0)
    write_file(f"players/{unique_id}/active.txt", 0)
    write_file(f"players/{unique_id}/ip.txt", "0.0.0.0")
    write_file(f"players/{unique_id}/local_id.txt", 0)
    
    ti_on_player_deconnect(unique_id, local_id)
"""

functions/files_functions.py
"""
import os

def make_dir(path):
    os.makedirs(path, mode=0o700, exist_ok=True)

def move_file_contents(file_source, file_output, delete=False):
    contents = read_file(file_source)
    write_file(file_output, contents)
    
    if delete:
        write_file(file_source, 0)

def read_file(file_path):
    if os.path.exists(file_path):
        with open(file_path, 'r') as file:
            return file.read()
    return 0

def write_file(file_path, contents):
    with open(file_path, 'w') as file:
        file.write(str(contents))
"""


functions/functions.py
"""
from server_config import *  # Include server configuration

from functions.hardwired_functions import *
from functions.init_player import *
from functions.deconnect_player import *
from functions.troops_functions import *
from functions.player_id_functions import *
from functions.player_functions import *
from functions.files_functions import *
from functions.other_functions import *

from triggers.on_connect import *
from triggers.on_deconnect import *
"""


functions/init_player.py
"""
from functions.hardwired_functions import *
from functions.init_player import *
from functions.deconnect_player import *
from functions.troops_functions import *
from functions.player_id_functions import *
from functions.player_functions import *
from functions.files_functions import *
from functions.other_functions import *

def init_player(unique_id, username, starting_gold):
    player_root = f"players/{unique_id}/"
    make_dir(player_root + "to_send")
    
    for i in range(1, 11):
        write_file(player_root + f"to_send/{i}.txt", '0')
        write_file(player_root + f"to_send/nr_string_{i}.txt", '0')
    
    write_file(player_root + "position.txt", "0|0|0")
    write_file(player_root + "username.txt", username)
    write_file(player_root + "local_id.txt", '0')
    write_file(player_root + "ip.txt", '0')
    write_file(player_root + "active.txt", '0')
    write_file(player_root + "last_time_active.txt", '0')
    write_file(player_root + "ping.txt", '0')
    write_file(player_root + "ping_var.txt", '0')
    write_file(player_root + "gold.txt", starting_gold)
    
    inv = '-1'
    for i in range(1, 92):
        inv += '|-1'
    write_file(player_root + "inventory.txt", inv)
    
    troops = '-1|-1|0'
    for i in range(1, 40):
        troops += '|-1'
    write_file(player_root + "troops.txt", troops)
"""

functions/hardwired_functions.py
"""
from functions.hardwired_functions import *
from functions.init_player import *
from functions.deconnect_player import *
from functions.troops_functions import *
from functions.player_id_functions import *
from functions.player_functions import *
from functions.files_functions import *
from functions.other_functions import *

import os
import shutil

dev_log = False

def send_data(unique_id):
    global dev_log
    
    total_length = 0
    output = ''
    
    for i in range(1, 11):
        args = read_file(f'players/{unique_id}/to_send/{i}.txt').split('|')
        nr_str = read_file(f'players/{unique_id}/to_send/nr_string_{i}.txt')
        nr_arg = len(args) - 1
        
        if total_length + nr_arg < 100 and nr_arg != 0 and read_file(f'players/{unique_id}/to_send/{i}.txt') != "0":
            total_length += nr_arg
            output += f'{nr_arg}|{nr_str}|' + "|".join(args) + '|'
            
            # Deleting the data
            write_file(f'players/{unique_id}/to_send/{i}.txt', 0)
            write_file(f'players/{unique_id}/to_send/nr_string_{i}.txt', 0)
    
    # Increasing the priority of the remaining data
    j = 1
    for i in range(1, 11):
        nr_arg = read_file(f'players/{unique_id}/to_send/nr_{i}.txt')
        if nr_arg != "0":
            move_file_contents(f'players/{unique_id}/to_send/{i}.txt', f'players/{unique_id}/to_send/{j}.txt', 1)
            move_file_contents(f'players/{unique_id}/to_send/nr_string_{i}.txt', f'players/{unique_id}/to_send/nr_string_{j}.txt', 1)
            j += 1
    
    print(output)
    
    if dev_log:
        save_to_log(output, 1)

def send_data_to_player(player_id, data, nr_strings=0):
    slot = 10
    for i in range(1, 11):
        args = read_file(f'players/{player_id}/to_send/{i}.txt').split('|')
        nr_arg = len(args) - 1
        if nr_arg == 0:
            slot = i
            break
    
    nr_args = len(data) - 1
    output = data[0]
    for i in range(1, nr_args + 1):
        output += f'|{data[i]}'
    
    write_file(f'players/{player_id}/to_send/{slot}.txt', output)
    write_file(f'players/{player_id}/to_send/nr_string_{slot}.txt', nr_strings)
    
    return output
"""


functions/other_functions.py
"""
import re
from functions.hardwired_functions import *
from functions.init_player import *
from functions.deconnect_player import *
from functions.troops_functions import *
from functions.player_id_functions import *
from functions.player_functions import *
from functions.files_functions import *
from functions.other_functions import *


def check_players_activity():
    for i in range(1, 11):
        unique_id = read_file(f"local_id/{i}.txt")
        if unique_id != '0':
            last_time_active = read_file(f"players/{unique_id}/last_time_active.txt")
            if time() - float(last_time_active) > 3:  # if more than 3 seconds passed since last active
                deconnect_player(unique_id)

def microtime_float():
    usec, sec = time().split(" ")
    return float(usec) + float(sec)

def check_string(string):
    if re.match("^[a-zA-Z0-9\_\-\[\]\~]+$", string):
        return 1
    else:
        return 0

def send_initial_players(unique_id):
    nr_players = 0
    to_send = [8]
    c = 1
    for i in range(1, 11):
        u_id = get_unique_id_by_local(i)
        if u_id != 0:
            position = get_position(u_id)
            x, y, rot = position[0], position[1], position[2]
            
            to_send.extend([x, y, rot, get_player_username(u_id), get_active(u_id)])
        else:
            to_send.extend([0, 0, 0, "Offline", 0])
    
    send_data_to_player(unique_id, to_send, 10)

def save_to_log(string, dev=0):
    if dev:
        with open(dev_log_path, 'a') as fh:
            fh.write(f"{get_client_ip()} -- {get_request_uri()} --- {string}\n")
    else:
        if server_log:
            with open(server_log_path, 'a') as fh:
                fh.write(f"{string}\n")
"""


functions/player_functions.py
"""
from functions.hardwired_functions import *
from functions.init_player import *
from functions.deconnect_player import *
from functions.troops_functions import *
from functions.player_id_functions import *
from functions.player_functions import *
from functions.files_functions import *
from functions.other_functions import *

def get_active(unique_id):
    return read_file(f'players/{unique_id}/active.txt')

def get_position(unique_id):
    position = read_file(f'players/{unique_id}/position.txt')
    array = position.split("|")
    return array

def get_gold(unique_id):
    return read_file(f'players/{unique_id}/gold.txt')

def get_last_time_active(unique_id):
    return read_file(f'players/{unique_id}/last_time.txt')

def inventory_get_slot(unique_id, slot):
    inv = read_file(f'players/{unique_id}/inventory.txt')
    inv_array = inv.split("|")
    return inv_array[slot]

def inventory_set_slot(unique_id, slot, value):
    inv = read_file(f'players/{unique_id}/inventory.txt')
    inv_array = inv.split("|")
    inv_array[slot] = value
    to_write = "|".join(inv_array)
    write_file(f'players/{unique_id}/inventory.txt', to_write)

def set_last_time_active(unique_id):
    write_file(f'players/{unique_id}/last_time.txt', time())

def set_position(unique_id, x, y, rot):
    write_file(f'players/{unique_id}/position.txt', f'{x}|{y}|{rot}')

def set_gold(unique_id, gold):
    write_file(f'players/{unique_id}/gold.txt', gold)

def set_active(unique_id, state):
    write_file(f'players/{unique_id}/active.txt', state)
"""


functions/player_id_functions.py
"""
from flask import request
from functions.hardwired_functions import *
from functions.init_player import *
from functions.deconnect_player import *
from functions.troops_functions import *
from functions.player_id_functions import *
from functions.player_functions import *
from functions.files_functions import *
from functions.other_functions import *


def read_file(filename):
    with open(filename, 'r') as file:
        return file.read().strip()

def find_local_id(id):
    for i in range(1, 11):
        file_id = read_file(f"local_id/{i}.txt")
        if file_id == id:
            return i
    return 0

def get_player_ip():
    print(request.remote_addr)
    return request.remote_addr

def get_unique_id_by_username(username):
    return read_file(f"username_id/{username}.txt")

def get_unique_id_by_local(local):
    return read_file(f"local_id/{local}.txt")

def get_player_username(unique_id):
    return read_file(f"players/{unique_id}/username.txt")

def get_local_id_by_ip(ip=0):
    if ip == 0:
        return read_file(f"ip_login/{request.remote_addr}.txt")
    else:
        return read_file(f"ip_login/{ip}.txt")

def get_local_id_by_unique(unique_id):
    return read_file(f"players/{unique_id}/local_id.txt")


"""


functions/send_initial_players.py
"""
from hardwired_functions import *
from init_player import *
from deconnect_player import *
from troops_functions import *
from player_id_functions import *
from player_functions import *
from files_functions import *
from other_functions import *


def send_initial_players(unique_id):
    nr_players = 0
    to_send = [8]
    c = 1
    for i in range(1, 11):
        u_id = get_unique_id_by_local(i)
        if u_id != 0:
            position = get_position(u_id)
            x, y, rot = position[0], position[1], position[2]
            
            to_send.extend([x, y, rot, get_player_username(u_id), get_active(u_id)])
        else:
            to_send.extend([0, 0, 0, "Offline", 0])
    
    send_data_to_player(unique_id, to_send, 10)
"""


functions/troops_functions.py
"""
from functions.hardwired_functions import *
from functions.init_player import *
from functions.deconnect_player import *
from functions.troops_functions import *
from functions.player_id_functions import *
from functions.player_functions import *
from functions.files_functions import *
from functions.other_functions import *


def player_get_troop_id(unique_id, troop_slot):
    troop = read_file(f"players/{unique_id}/troops.txt")
    array = troop.split("|")
    return array[troop_slot]

def player_set_troop_slot(unique_id, slot, troop_id):
    troop = read_file(f"players/{unique_id}/troops.txt")
    array = troop.split("|")
    array[slot] = troop_id
    to_write = "|".join(array)
    write_file(f"players/{unique_id}/troops.txt", to_write)
"""


triggers/on_connect.py
"""
from functions.hardwired_functions import *
from functions.init_player import *
from functions.deconnect_player import *
from functions.troops_functions import *
from functions.player_id_functions import *
from functions.player_functions import *
from functions.files_functions import *
from functions.other_functions import *


def ti_on_player_connect(unique_id):
    username = get_player_username(unique_id)
    local_id = get_local_id_by_unique(unique_id)
    
    # send player log in to all active players
    for i in range(1, 11):
        u_id = get_unique_id_by_local(i)
        if u_id != 0:
            send_data_to_player(u_id, [7, 1, local_id, username], 1)  # player log in!
    
    position = get_position(unique_id)
    x = position[0]
    y = position[1]
    rot = position[2]
    
    to_send = [5, x, y, rot]
    
    send_data_to_player(unique_id, to_send)
    
    save_to_log(username + ' connected with ip ' + get_player_ip())
    
    send_data_to_player(unique_id, [15, "NEW WEBSERVER! " + username + "!^Welcome to my coop server!", 0xA0EDF7, 1])
"""

triggers/on_deconnect.py
"""
from functions.hardwired_functions import *
from functions.init_player import *
from functions.deconnect_player import *
from functions.troops_functions import *
from functions.player_id_functions import *
from functions.player_functions import *
from functions.files_functions import *
from functions.other_functions import *

def ti_on_player_deconnect(unique_id, local_id):
    username = get_player_username(unique_id)
    
    for j in range(1, 11):
        u_id = get_unique_id_by_local(j)
        if u_id != 0 and u_id != unique_id:
            send_data_to_player(u_id, [7, 2, local_id, username], 1)  # player disconnect
    
    save_to_log(username + ' lost connection/disconnect')
"""

What's wrong with whole code? Tell where you need to fix and give the code + make it work with Flask (in the browser output to 127.0.0.0.1:5000/mutliplayer should be output "1|0|2|0|", all other requests should have their own).
Example request from devlog: 127.0.0.0.1--/multiplayer.php?&event1=4&nrarg1=4&arg1%7C1=0&arg1%7C2=0&arg1%7C3=0 ---