<commit_before>import binascii
import os
import struct
import sys
import textwrap
import requests
from PIL import Image
from ninfile2 import GameTDB


def u8(data):
    if not 0 <= data <= 255:
        log("u8 out of range: %s" % data, "INFO")
        data = 0
    return struct.pack(">B", data)


def u16(data):
    if not 0 <= data <= 65535:
        log("u16 out of range: %s" % data, "INFO")
        data = 0
    return struct.pack(">H", data)


def u32(data):
    if not 0 <= data <= 4294967295:
        log("u32 out of range: %s" % data, "INFO")
        data = 0
    return struct.pack(">I", data)


def u32_littleendian(data):
    if not 0 <= data <= 4294967295:
        log("u32 little endian out of range: %s" % data, "INFO")
        data = 0
    return struct.pack("<I", data)


if len(sys.argv) != 3:
    print("Usage: info.py <platform> <title id>")
    sys.exit(1)
elif len(sys.argv[2]) != 4:
    print("Error: Title ID must be 4 characters.")
    sys.exit(1)


def enc(text, length):
    if len(text) > length:
        print("Error: Text too long.")
        sys.exit(1)
    return text.encode("utf-16be").ljust(length, b'\0')[:length]


class make_info():
    def __init__(self, databases):
        self.databases = databases

        self.make_header()
        self.write_gametdb_info()
        self.write_file()
        self.insert_image()

        print("Completed Successfully")

    def make_header(self):
        self.header = {}

        self.header["unknown"] = u16(0)
        self.header["version"] = u8(6)
        self.header["unknown_region"] = u8(2)
        self.header["filesize"] = u32(0)
        self.header["crc32"] = u32(0)
        self.header["dllistid"] = u32(0)
        self.header["country_code"] = u32(49)
        self.header["language_code"] = u32(1)
        self.header["ratings_table_offset"] = u32(0)
        self.header["times_played_table_offset"] = u32(0)
        self.header["people_who_liked_this_also_liked_entry_number"] = u32(0)
        self.header["people_who_liked_this_also_liked_table_offset"] = u32(0)
        self.header["related_titles_entry_number"] = u32(0)
        self.header["related_titles_table_offset"] = u32(0)
        self.header["videos_entry_number"] = u32(0)
        self.header["videos_table_offset"] = u32(0)
        self.header["demos_entry_number"] = u32(0)
        self.header["demos_table_offset"] = u32(0)
        self.header["unknown_2"] = u32(0) * 2
        self.header["picture_offset"] = u32(0x2351)
        # The channel only seems to care if this offset is lower than the last offset in the file.
        # If this offset is lower, then the image will not display. I am pretty sure no covers in GameTDB are larger than 36 KB.
        self.header["picture_size"] = u32(0x9999)
        self.header["unknown_3"] = u32(0)
        self.header["rating_picture_offset"] = u32(0)
        self.header["rating_picture_size"] = u32(0)
        for i in range(1, 8):
            self.header["rating_detail_picture_%s_size" % i] = u32(0)
            self.header["rating_detail_picture_%s_offset" % i] = u32(0)
        self.header["unknown_4"] = u32(0) * 2
        self.header["soft_id"] = u32(0)
        self.header["game_id"] = u32(0)
        self.header["platform_flag"] = u8(0)
        self.header["company_id"] = u32(0)
        self.header["unknown_5"] = u16(0)
        self.header["unknown_6"] = u16(0)
        self.header["unknown_7"] = u8(0)
        self.header["wii_shop_channel_button_flag"] = u8(0)
        self.header["purchase_button_flag"] = u8(0)
        self.header["release_year"] = u16(0)
        self.header["release_month"] = u8(0)
        self.header["release_day"] = u8(0)
        self.header["shop_points"] = u32(0)
        for i in range(1, 5):
            self.header["unknown_8_%s" % i] = u8(0)
        self.header["wii_remote_flag"] = u8(0)
        self.header["nunchuk_flag"] = u8(0)
        self.header["classic_controller_flag"] = u8(0)
        self.header["gamecube_controller_flag"] = u8(0)
        self.header["mii_flag"] = u8(0)
        self.header["online_flag"] = u8(0)
        self.header["wiiconnect24_flag"] = u8(0)
        self.header["nintendo_wifi_connection_flag"] = u8(0)
        self.header["downloadable_content_flag"] = u8(0)
        self.header["wireless_play_flag"] = u8(0)
        self.header["download_play_flag"] = u8(0)
        self.header["touch_generations_flag"] = u8(0)
        self.header["language_chinese_flag"] = u8(0)
        self.header["language_korean_flag"] = u8(0)
        self.header["language_japanese_flag"] = u8(0)
        self.header["language_english_flag"] = u8(0)
        self.header["language_french_flag"] = u8(0)
        self.header["language_spanish_flag"] = u8(0)
        self.header["language_german_flag"] = u8(0)
        self.header["language_italian_flag"] = u8(0)
        self.header["language_dutch_flag"] = u8(0)
        for i in range(1, 11):
            self.header["unknown_9_%s" % i] = u8(0)
        self.header["title"] = b'\0' * 62
        self.header["subtitle"] = b'\0' * 62
        self.header["short_title"] = b'\0' * 62
        for i in range(1, 4):
            self.header["description_text_%s" % i] = b'\0' * 82
        self.header["genre_text"] = b'\0' * 58
        self.header["players_text"] = b'\0' * 82
        self.header["peripherals_text"] = b'\0' * 88
        self.header["unknown_10"] = b'\0' * 80
        self.header["disclaimer_text"] = b'\0' * 4800
        self.header["unknown_11"] = u8(0)
        self.header["distribution_date_text"] = b'\0' * 82
        self.header["wii_points_text"] = b'\0' * 82
        for i in range(1, 11):
            self.header["custom_field_text_%s" % i] = b'\0' * 82

    def write_gametdb_info(self):
        for s in self.databases[sys.argv[1]][1].findall("game"):
            if s.find("id").text[:4] == sys.argv[2] and s.find("type") != "CUSTOM":
                print("Found {}!".format(sys.argv[2]))
                self.header["game_id"] = sys.argv[2].encode("utf-8")

                self.header["purchase_button_flag"] = u8(1)  # we'll make it go to gametdb
                self.header["release_year"] = u16(int(s.find("date").get("year")))
                self.header["release_month"] = u8(int(s.find("date").get("month")) - 1)
                self.header["release_day"] = u8(int(s.find("date").get("day")))

                controllers = {"wiimote": "wii_remote", "nunchuk": "nunchuk", "classiccontroller": "classic_controller",
                               "gamecube": "gamecube_controller", "mii": "mii"}
                controllers2 = {"wheel": "Wii Wheel", "balanceboard": "Wii Balance Board", "wiispeak": "Wii Speak",
                                "microphone": "Microphone", "guitar": "Guitar", "drums": "Drums",
                                "dancepad": "Dance Pad", "keyboard": "Keyboard", "udraw": "uDraw"}

                other_peripherals = False

                for controller in s.find("input").findall("control"):
                    if controller.get("type") in controllers:
                        self.header["{}_flag".format(controllers[controller.get("type")])] = u8(1)
                    elif controller.get("type") in controllers2:
                        if not other_peripherals:
                            self.header["peripherals_text"] = ""

                        self.header["peripherals_text"] += controllers2[controller.get("type")] + ", "

                        other_peripherals = True

                if other_peripherals:
                    self.header["peripherals_text"] = enc(self.header["peripherals_text"][:-2], 88)

                for feature in s.find("wi-fi").findall("feature"):
                    if "online" in feature.text:
                        self.header["online_flag"] = u8(1)
                        self.header["nintendo_wifi_connection_flag"] = u8(1)<commit_msg>Now specifies which type of game it is<commit_after>import binascii
import os
import struct
import sys
import textwrap
import requests
from PIL import Image
from ninfile2 import GameTDB


def u8(data):
    if not 0 <= data <= 255:
        log("u8 out of range: %s" % data, "INFO")
        data = 0
    return struct.pack(">B", data)


def u16(data):
    if not 0 <= data <= 65535:
        log("u16 out of range: %s" % data, "INFO")
        data = 0
    return struct.pack(">H", data)


def u32(data):
    if not 0 <= data <= 4294967295:
        log("u32 out of range: %s" % data, "INFO")
        data = 0
    return struct.pack(">I", data)


def u32_littleendian(data):
    if not 0 <= data <= 4294967295:
        log("u32 little endian out of range: %s" % data, "INFO")
        data = 0
    return struct.pack("<I", data)


if len(sys.argv) != 3:
    print("Usage: info.py <platform> <title id>")
    sys.exit(1)
elif len(sys.argv[2]) != 4:
    print("Error: Title ID must be 4 characters.")
    sys.exit(1)


def enc(text, length):
    if len(text) > length:
        print("Error: Text too long.")
        sys.exit(1)
    return text.encode("utf-16be").ljust(length, b'\0')[:length]


class make_info():
    def __init__(self, databases):
        self.databases = databases

        self.make_header()
        self.write_gametdb_info()
        self.write_file()
        self.insert_image()

        print("Completed Successfully")

    def make_header(self):
        self.header = {}

        self.header["unknown"] = u16(0)
        self.header["version"] = u8(6)
        self.header["unknown_region"] = u8(2)
        self.header["filesize"] = u32(0)
        self.header["crc32"] = u32(0)
        self.header["dllistid"] = u32(0)
        self.header["country_code"] = u32(49)
        self.header["language_code"] = u32(1)
        self.header["ratings_table_offset"] = u32(0)
        self.header["times_played_table_offset"] = u32(0)
        self.header["people_who_liked_this_also_liked_entry_number"] = u32(0)
        self.header["people_who_liked_this_also_liked_table_offset"] = u32(0)
        self.header["related_titles_entry_number"] = u32(0)
        self.header["related_titles_table_offset"] = u32(0)
        self.header["videos_entry_number"] = u32(0)
        self.header["videos_table_offset"] = u32(0)
        self.header["demos_entry_number"] = u32(0)
        self.header["demos_table_offset"] = u32(0)
        self.header["unknown_2"] = u32(0) * 2
        self.header["picture_offset"] = u32(0x2351)
        # The channel only seems to care if this offset is lower than the last offset in the file.
        # If this offset is lower, then the image will not display. I am pretty sure no covers in GameTDB are larger than 36 KB.
        self.header["picture_size"] = u32(0x9999)
        self.header["unknown_3"] = u32(0)
        self.header["rating_picture_offset"] = u32(0)
        self.header["rating_picture_size"] = u32(0)
        for i in range(1, 8):
            self.header["rating_detail_picture_%s_size" % i] = u32(0)
            self.header["rating_detail_picture_%s_offset" % i] = u32(0)
        self.header["unknown_4"] = u32(0) * 2
        self.header["soft_id"] = u32(0)
        self.header["game_id"] = u32(0)
        self.header["platform_flag"] = u8(0)
        self.header["company_id"] = u32(0)
        self.header["unknown_5"] = u16(0)
        self.header["unknown_6"] = u16(0)
        self.header["unknown_7"] = u8(0)
        self.header["wii_shop_channel_button_flag"] = u8(0)
        self.header["purchase_button_flag"] = u8(0)
        self.header["release_year"] = u16(0)
        self.header["release_month"] = u8(0)
        self.header["release_day"] = u8(0)
        self.header["shop_points"] = u32(0)
        for i in range(1, 5):
            self.header["unknown_8_%s" % i] = u8(0)
        self.header["wii_remote_flag"] = u8(0)
        self.header["nunchuk_flag"] = u8(0)
        self.header["classic_controller_flag"] = u8(0)
        self.header["gamecube_controller_flag"] = u8(0)
        self.header["mii_flag"] = u8(0)
        self.header["online_flag"] = u8(0)
        self.header["wiiconnect24_flag"] = u8(0)
        self.header["nintendo_wifi_connection_flag"] = u8(0)
        self.header["downloadable_content_flag"] = u8(0)
        self.header["wireless_play_flag"] = u8(0)
        self.header["download_play_flag"] = u8(0)
        self.header["touch_generations_flag"] = u8(0)
        self.header["language_chinese_flag"] = u8(0)
        self.header["language_korean_flag"] = u8(0)
        self.header["language_japanese_flag"] = u8(0)
        self.header["language_english_flag"] = u8(0)
        self.header["language_french_flag"] = u8(0)
        self.header["language_spanish_flag"] = u8(0)
        self.header["language_german_flag"] = u8(0)
        self.header["language_italian_flag"] = u8(0)
        self.header["language_dutch_flag"] = u8(0)
        for i in range(1, 11):
            self.header["unknown_9_%s" % i] = u8(0)
        self.header["title"] = b'\0' * 62
        self.header["subtitle"] = b'\0' * 62
        self.header["short_title"] = b'\0' * 62
        for i in range(1, 4):
            self.header["description_text_%s" % i] = b'\0' * 82
        self.header["genre_text"] = b'\0' * 58
        self.header["players_text"] = b'\0' * 82
        self.header["peripherals_text"] = b'\0' * 88
        self.header["unknown_10"] = b'\0' * 80
        self.header["disclaimer_text"] = b'\0' * 4800
        self.header["unknown_11"] = u8(0)
        self.header["distribution_date_text"] = b'\0' * 82
        self.header["wii_points_text"] = b'\0' * 82
        for i in range(1, 11):
            self.header["custom_field_text_%s" % i] = b'\0' * 82

    def write_gametdb_info(self):
        for s in self.databases[sys.argv[1]][1].findall("game"):
            if s.find("id").text[:4] == sys.argv[2] and s.find("type") != "CUSTOM":
                print("Found {}!".format(sys.argv[2]))
                self.header["game_id"] = sys.argv[2].encode("utf-8")

                # Get the game type
                game_type = {"VC-NES": 0x03, "VC-SNES": 0x04, "VC-N64": 0x05, "VC-SMS": 0x0C, "VC-MD": 0x07,
                             "VC-PCE": 0x06, "VC-C64": 0x0D, "VC-NEOGEO": 0x08, "VC-Arcade": 0x0E, "Channel": 0x02,
                             None: 0x01, "WiiWare": 0x0B}
                                                    # The XML returns None for disc games when we query the type.
                if s.find("type").text in game_type:
                    self.header["platform_flag"] = u8(game_type[s.find("type").text])
                else:
                    print("Could not find game type")
                    sys.exit(1)

                self.header["purchase_button_flag"] = u8(1)  # we'll make it go to gametdb
                self.header["release_year"] = u16(int(s.find("date").get("year")))
                self.header["release_month"] = u8(int(s.find("date").get("month")) - 1)
                self.header["release_day"] = u8(int(s.find("date").get("day")))

                controllers = {"wiimote": "wii_remote", "nunchuk": "nunchuk", "classiccontroller": "classic_controller",
                               "gamecube": "gamecube_controller", "mii": "mii"}
                controllers2 = {"wheel": "Wii Wheel", "balanceboard": "Wii Balance Board", "wiispeak": "Wii Speak",
                                "microphone": "Microphone", "guitar": "Guitar", "drums": "Drums",
                                "dancepad": "Dance Pad", "keyboard": "Keyboard", "udraw": "uDraw"}

                other_peripherals = False

                for controller in s.find("input").findall("control"):
                    if controller.get("type") in controllers:
                        self.header["{}_flag".format(controllers[controller.get("type")])] = u8(1)
                    elif controller.get("type") in controllers2:
                        if not other_peripherals:
                            self.header["peripherals_text"] = ""

                        self.header["peripherals_text"] += controllers2[controller.get("type")] + ", "

                        other_peripherals = True

                if other_peripherals:
                    self.header["peripherals_text"] = enc(self.header["peripherals_text"][:-2], 88)

                for feature in s.find("wi-fi").findall("feature"):
                    if "online" in feature.text:
                        self.header["online_flag"] = u8(1)
                        self.header["nintendo_wifi_connection_flag"] = u8(1)
{'fraction_non_alphanumeric': 0.15553795540392348, 'fraction_numerical': 0.04203728524430364, 'mean_word_length': 2.3782671331549703, 'pattern_counts': {'":': 41, '<': 25, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '225304', 'n_tokens_mistral': 5896, 'n_tokens_neox': 5493, 'n_words': 1048}