Refactor function positioning, add beginning support for using json keys to limit rows

This commit is contained in:
Ahrimdon 2024-03-03 02:18:12 -05:00
parent e44f9c2b41
commit b91eea00a9

View File

@ -8,6 +8,7 @@ Description: This script parses key elements of IW4MAdmin's database into a sing
import sqlite3 import sqlite3
import argparse import argparse
import time import time
import json
import os import os
import re import re
@ -16,6 +17,7 @@ def setup_argparser():
parser.add_argument('-p', '--path', type=str, default="Database.db", help="Path to the IW4MAdmin database file.") parser.add_argument('-p', '--path', type=str, default="Database.db", help="Path to the IW4MAdmin database file.")
parser.add_argument('-o', '--output', type=str, help="Output directory for the parsed database file.") parser.add_argument('-o', '--output', type=str, help="Output directory for the parsed database file.")
parser.add_argument('-t', '--time', action='store_true', help="Time the script's execution.") parser.add_argument('-t', '--time', action='store_true', help="Time the script's execution.")
parser.add_argument('-c', '--config', type=str, help="Path to the configuration file.")
return parser.parse_args() return parser.parse_args()
def delete_existing_db(output_db_path): def delete_existing_db(output_db_path):
@ -24,12 +26,40 @@ def delete_existing_db(output_db_path):
os.remove(output_db_path) os.remove(output_db_path)
print(f"Existing parsed database at {output_db_path} has been removed.") print(f"Existing parsed database at {output_db_path} has been removed.")
def load_or_create_config(config_path):
default_config = {
"tables": {
"AuditLog": 1000, # Example default value
"ClientConnectionHistory": 1000,
"ClientMessages": 1000,
"Clients": 1000,
"IPAddresses": 1000,
"InboxMessagesModified": 1000,
"Maps": 1000,
"Metadata": 1000,
"Penalties": 1000,
"PenaltyIdentifiers": 1000,
"Servers": 1000
}
}
if not os.path.isfile(config_path):
with open(config_path, 'w') as config_file:
json.dump(default_config, config_file, indent=4)
print(f"Default configuration file created at {config_path}")
else:
with open(config_path, 'r') as config_file:
return json.load(config_file)
def main(): def main():
args = setup_argparser() args = setup_argparser()
if args.time: if args.time:
start_time = time.time() # Start timing start_time = time.time() # Start timing
config = {}
if args.config:
config = load_or_create_config(args.config)
db_path = args.path db_path = args.path
output_dir = args.output if args.output else '.' # Use current directory if no output directory is specified output_dir = args.output if args.output else '.' # Use current directory if no output directory is specified
output_db_path = os.path.join(output_dir, "Database_parsed.db") output_db_path = os.path.join(output_dir, "Database_parsed.db")
@ -54,17 +84,67 @@ def main():
new_cur = new_conn.cursor() new_cur = new_conn.cursor()
# Process each table # Process each table
ip_address_table(existing_cur, new_cur) if 'AuditLog' in config.get('tables', {}):
audit_log_limit = config['tables']['AuditLog']
audit_log_table(existing_cur, new_cur, limit=audit_log_limit)
else:
audit_log_table(existing_cur, new_cur) audit_log_table(existing_cur, new_cur)
client_connection_table(existing_cur, new_cur)
messages_table(existing_cur, new_cur) if 'ClientConnectionHistory' in config.get('tables', {}):
client_table(existing_cur, new_cur) client_connection_history_limit = config['tables']['ClientConnectionHistory']
client_connection_history_table(existing_cur, new_cur, limit=client_connection_history_limit)
else:
client_connection_history_table(existing_cur, new_cur)
if 'ClientMessages' in config.get('tables', {}):
client_messages_limit = config['tables']['ClientMessages']
client_messages_table(existing_cur, new_cur, limit=client_messages_limit)
else:
client_messages_table(existing_cur, new_cur)
if 'Clients' in config.get('tables', {}):
clients_limit = config['tables']['Clients']
clients_table(existing_cur, new_cur, limit=clients_limit)
else:
clients_table(existing_cur, new_cur)
ip_address_table(existing_cur, new_cur)
if 'InboxMessagesModified' in config.get('tables', {}):
inbox_messages_modified_limit = config['tables']['InboxMessagesModified']
inbox_messages_modified_table(existing_cur, new_cur, limit=inbox_messages_modified_limit)
else:
inbox_messages_modified_table(existing_cur, new_cur)
if 'Maps' in config.get('tables', {}):
maps_limit = config['tables']['Maps']
maps_table(existing_cur, new_cur, limit=maps_limit)
else:
maps_table(existing_cur, new_cur) maps_table(existing_cur, new_cur)
meta_table(existing_cur, new_cur)
if 'Metadata' in config.get('tables', {}):
metadata_limit = config['tables']['Metadata']
metadata_table(existing_cur, new_cur, limit=metadata_limit)
else:
metadata_table(existing_cur, new_cur)
if 'Penalties' in config.get('tables', {}):
penalties_limit = config['tables']['Penalties']
penalties_table(existing_cur, new_cur, limit=penalties_limit)
else:
penalties_table(existing_cur, new_cur) penalties_table(existing_cur, new_cur)
penalty_Identifiers_table(existing_cur, new_cur)
if 'PenaltyIdentifiers' in config.get('tables', {}):
penalty_identifiers_limit = config['tables']['PenaltyIdentifiers']
penalty_identifiers_table(existing_cur, new_cur, limit=penalty_identifiers_limit)
else:
penalty_identifiers_table(existing_cur, new_cur)
if 'Servers' in config.get('tables', {}):
servers_limit = config['tables']['Servers']
servers_table(existing_cur, new_cur, limit=servers_limit)
else:
servers_table(existing_cur, new_cur) servers_table(existing_cur, new_cur)
inbox_messages_table(existing_cur, new_cur)
# Commit and close # Commit and close
new_conn.commit() new_conn.commit()
@ -75,35 +155,7 @@ def main():
end_time = time.time() # End timing end_time = time.time() # End timing
print(f"Script execution time: {end_time - start_time:.4f} seconds") # Print execution time print(f"Script execution time: {end_time - start_time:.4f} seconds") # Print execution time
def ip_address_table(existing_cur, new_cur): def audit_log_table(existing_cur, new_cur, limit=None):
def fetch_client_info(src_cur):
src_cur.execute("""
SELECT Name, SearchableIPAddress, DateAdded FROM EFAlias
""")
client_info = []
for row in src_cur.fetchall():
name = row[0].replace('^7', '')
client_info.append((name, row[1], row[2]))
return client_info
client_info = fetch_client_info(existing_cur)
new_cur.execute("""
CREATE TABLE IF NOT EXISTS "IPAddresses" (
Name TEXT NOT NULL,
SearchableIPAddress TEXT,
DateAdded TEXT NOT NULL
)
""")
new_cur.executemany("""
INSERT INTO "IPAddresses" (
Name, SearchableIPAddress, DateAdded
) VALUES (?, ?, ?)
""", client_info)
def audit_log_table(existing_cur, new_cur):
new_cur.execute(""" new_cur.execute("""
CREATE TABLE "AuditLog" ( CREATE TABLE "AuditLog" (
"ChangeHistoryId" INTEGER NOT NULL, "ChangeHistoryId" INTEGER NOT NULL,
@ -117,7 +169,7 @@ def audit_log_table(existing_cur, new_cur):
) )
""") """)
existing_cur.execute(""" query = """
SELECT SELECT
EFChangeHistory.ChangeHistoryId, EFChangeHistory.ChangeHistoryId,
EFChangeHistory.TypeOfChange, EFChangeHistory.TypeOfChange,
@ -128,7 +180,11 @@ def audit_log_table(existing_cur, new_cur):
EFChangeHistory.TargetEntityId EFChangeHistory.TargetEntityId
FROM FROM
EFChangeHistory EFChangeHistory
""") """
if limit:
query += f" LIMIT {limit}"
existing_cur.execute(query)
rows = existing_cur.fetchall() rows = existing_cur.fetchall()
client_name_map = {} client_name_map = {}
@ -178,7 +234,7 @@ def audit_log_table(existing_cur, new_cur):
new_row = (row[0], type_of_change, row[2], row[3], row[4], client_name_map[origin_entity_id], client_name_map[target_entity_id]) new_row = (row[0], type_of_change, row[2], row[3], row[4], client_name_map[origin_entity_id], client_name_map[target_entity_id])
new_cur.execute("INSERT INTO \"AuditLog\" (ChangeHistoryId, TypeOfChange, Time, Data, Command, Origin, Target) VALUES (?, ?, ?, ?, ?, ?, ?)", new_row) new_cur.execute("INSERT INTO \"AuditLog\" (ChangeHistoryId, TypeOfChange, Time, Data, Command, Origin, Target) VALUES (?, ?, ?, ?, ?, ?, ?)", new_row)
def client_connection_table(existing_cur, new_cur): def client_connection_history_table(existing_cur, new_cur, limit=None):
new_cur.execute(""" new_cur.execute("""
CREATE TABLE "ClientConnectionHistory" ( CREATE TABLE "ClientConnectionHistory" (
"ConnectionId" INTEGER NOT NULL, "ConnectionId" INTEGER NOT NULL,
@ -190,7 +246,7 @@ def client_connection_table(existing_cur, new_cur):
) )
""") """)
existing_cur.execute(""" query = """
SELECT SELECT
EFClientConnectionHistory.ClientConnectionId, EFClientConnectionHistory.ClientConnectionId,
EFClientConnectionHistory.ClientId, EFClientConnectionHistory.ClientId,
@ -199,7 +255,11 @@ def client_connection_table(existing_cur, new_cur):
EFClientConnectionHistory.ServerId EFClientConnectionHistory.ServerId
FROM FROM
EFClientConnectionHistory EFClientConnectionHistory
""") """
if limit:
query += f" LIMIT {limit}"
existing_cur.execute(query)
rows = existing_cur.fetchall() rows = existing_cur.fetchall()
for row in rows: for row in rows:
@ -241,7 +301,7 @@ def client_connection_table(existing_cur, new_cur):
new_row = (row[0], client_name, row[2], connection_type, server_hostname) new_row = (row[0], client_name, row[2], connection_type, server_hostname)
new_cur.execute("INSERT INTO ClientConnectionHistory (ConnectionId, Client, ConnectionTime, ConnectionType, Server) VALUES (?, ?, ?, ?, ?)", new_row) new_cur.execute("INSERT INTO ClientConnectionHistory (ConnectionId, Client, ConnectionTime, ConnectionType, Server) VALUES (?, ?, ?, ?, ?)", new_row)
def messages_table(existing_cur, new_cur): def client_messages_table(existing_cur, new_cur, limit=None):
new_cur.execute(""" new_cur.execute("""
CREATE TABLE "ClientMessages" ( CREATE TABLE "ClientMessages" (
"MessageId" INTEGER NOT NULL, "MessageId" INTEGER NOT NULL,
@ -253,7 +313,7 @@ def messages_table(existing_cur, new_cur):
) )
""") """)
existing_cur.execute(""" query = """
SELECT SELECT
EFClientMessages.MessageId, EFClientMessages.MessageId,
EFClientMessages.ClientId, EFClientMessages.ClientId,
@ -262,7 +322,11 @@ def messages_table(existing_cur, new_cur):
EFClientMessages.ServerId EFClientMessages.ServerId
FROM FROM
EFClientMessages EFClientMessages
""") """
if limit:
query += f" LIMIT {limit}"
existing_cur.execute(query)
rows = existing_cur.fetchall() rows = existing_cur.fetchall()
for row in rows: for row in rows:
@ -304,7 +368,7 @@ def messages_table(existing_cur, new_cur):
new_row = (row[0], client_name, row[2], row[3], server_hostname) new_row = (row[0], client_name, row[2], row[3], server_hostname)
new_cur.execute("INSERT INTO ClientMessages (MessageId, Client, Message, TimeSent, Server) VALUES (?, ?, ?, ?, ?)", new_row) new_cur.execute("INSERT INTO ClientMessages (MessageId, Client, Message, TimeSent, Server) VALUES (?, ?, ?, ?, ?)", new_row)
def client_table(existing_cur, new_cur): def clients_table(existing_cur, new_cur, limit=None):
new_cur.execute(""" new_cur.execute("""
CREATE TABLE "Clients" ( CREATE TABLE "Clients" (
"Connections" INTEGER NOT NULL, "Connections" INTEGER NOT NULL,
@ -319,7 +383,7 @@ def client_table(existing_cur, new_cur):
) )
""") """)
existing_cur.execute(""" query = """
SELECT SELECT
EFClients.Connections, EFClients.Connections,
EFClients.CurrentAliasId, EFClients.CurrentAliasId,
@ -334,7 +398,11 @@ def client_table(existing_cur, new_cur):
EFClients EFClients
JOIN JOIN
EFAlias ON EFClients.CurrentAliasId = EFAlias.AliasId EFAlias ON EFClients.CurrentAliasId = EFAlias.AliasId
""") """
if limit:
query += f" LIMIT {limit}"
existing_cur.execute(query)
rows = existing_cur.fetchall() rows = existing_cur.fetchall()
for row in rows: for row in rows:
@ -375,7 +443,72 @@ def client_table(existing_cur, new_cur):
new_row = (connections, client_name, first_connection, game, last_connection, level, masked, total_connection_time, ip_address) new_row = (connections, client_name, first_connection, game, last_connection, level, masked, total_connection_time, ip_address)
new_cur.execute("INSERT INTO Clients (Connections, Name, FirstConnection, Game, LastConnection, Level, Masked, TotalConnectionTime, IP) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", new_row) new_cur.execute("INSERT INTO Clients (Connections, Name, FirstConnection, Game, LastConnection, Level, Masked, TotalConnectionTime, IP) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", new_row)
def maps_table(existing_cur, new_cur): def ip_address_table(existing_cur, new_cur, limit=None):
def fetch_client_info(src_cur):
src_cur.execute("""
SELECT Name, SearchableIPAddress, DateAdded FROM EFAlias
""")
client_info = []
for row in src_cur.fetchall():
name = row[0].replace('^7', '')
client_info.append((name, row[1], row[2]))
return client_info
client_info = fetch_client_info(existing_cur)
new_cur.execute("""
CREATE TABLE IF NOT EXISTS "IPAddresses" (
Name TEXT NOT NULL,
SearchableIPAddress TEXT,
DateAdded TEXT NOT NULL
)
""")
new_cur.executemany("""
INSERT INTO "IPAddresses" (
Name, SearchableIPAddress, DateAdded
) VALUES (?, ?, ?)
""", client_info)
def inbox_messages_modified_table(existing_cur, new_cur, limit=None):
new_cur.execute("""
CREATE TABLE InboxMessagesModified (
InboxMessageId INTEGER PRIMARY KEY,
Created TEXT,
Origin TEXT,
Target TEXT,
ServerId INTEGER,
Message TEXT,
Read TEXT
)
""")
existing_cur.execute("SELECT * FROM InboxMessages")
inbox_messages = existing_cur.fetchall()
for msg in inbox_messages:
msg_id, created, _, source_client_id, dest_client_id, server_id, message, is_delivered = msg
for client_id in (source_client_id, dest_client_id):
existing_cur.execute("SELECT CurrentAliasId FROM EFClients WHERE ClientId = ?", (client_id,))
alias_id = existing_cur.fetchone()[0]
existing_cur.execute("SELECT Name FROM EFAlias WHERE AliasId = ?", (alias_id,))
name = existing_cur.fetchone()[0].replace('^7', '')
if client_id == source_client_id:
origin = name
else:
target = name
read = "Yes" if is_delivered == 1 else "No"
new_cur.execute("""
INSERT INTO InboxMessagesModified (InboxMessageId, Created, Origin, Target, ServerId, Message, Read)
VALUES (?, ?, ?, ?, ?, ?, ?)
""", (msg_id, created, origin, target, server_id, message, read))
def maps_table(existing_cur, new_cur, limit=None):
new_cur.execute(""" new_cur.execute("""
CREATE TABLE IF NOT EXISTS "Maps" ( CREATE TABLE IF NOT EXISTS "Maps" (
"MapId" INTEGER NOT NULL, "MapId" INTEGER NOT NULL,
@ -386,12 +519,16 @@ def maps_table(existing_cur, new_cur):
) )
""") """)
existing_cur.execute(""" query = """
SELECT SELECT
MapId, CreatedDateTime, Name, Game MapId, CreatedDateTime, Name, Game
FROM FROM
EFMaps EFMaps
""") """
if limit:
query += f" LIMIT {limit}"
existing_cur.execute(query)
rows = existing_cur.fetchall() rows = existing_cur.fetchall()
modified_rows = [] modified_rows = []
@ -406,7 +543,7 @@ def maps_table(existing_cur, new_cur):
) VALUES (?, ?, ?, ?) ) VALUES (?, ?, ?, ?)
""", modified_rows) """, modified_rows)
def meta_table(existing_cur, new_cur): def metadata_table(existing_cur, new_cur, limit=None):
new_cur.execute(""" new_cur.execute("""
CREATE TABLE "Metadata" ( CREATE TABLE "Metadata" (
"MetaId" INTEGER NOT NULL, "MetaId" INTEGER NOT NULL,
@ -417,7 +554,7 @@ def meta_table(existing_cur, new_cur):
) )
""") """)
existing_cur.execute(""" query = """
SELECT SELECT
EFMeta.MetaId, EFMeta.MetaId,
EFMeta.ClientId, EFMeta.ClientId,
@ -426,7 +563,11 @@ def meta_table(existing_cur, new_cur):
EFMeta.Value EFMeta.Value
FROM FROM
EFMeta EFMeta
""") """
if limit:
query += f" LIMIT {limit}"
existing_cur.execute(query)
rows = existing_cur.fetchall() rows = existing_cur.fetchall()
for row in rows: for row in rows:
@ -473,7 +614,7 @@ def meta_table(existing_cur, new_cur):
new_row = (meta_id, client_name, created, key, value) new_row = (meta_id, client_name, created, key, value)
new_cur.execute("INSERT INTO Metadata (MetaId, Name, Timestamp, Note, Value) VALUES (?, ?, ?, ?, ?)", new_row) new_cur.execute("INSERT INTO Metadata (MetaId, Name, Timestamp, Note, Value) VALUES (?, ?, ?, ?, ?)", new_row)
def penalties_table(existing_cur, new_cur): def penalties_table(existing_cur, new_cur, limit=None):
new_cur.execute(""" new_cur.execute("""
CREATE TABLE "Penalties" ( CREATE TABLE "Penalties" (
"PenaltyId" INTEGER NOT NULL, "PenaltyId" INTEGER NOT NULL,
@ -488,7 +629,7 @@ def penalties_table(existing_cur, new_cur):
) )
""") """)
existing_cur.execute(""" query = """
SELECT SELECT
EFPenalties.PenaltyId, EFPenalties.PenaltyId,
EFPenalties.AutomatedOffense, EFPenalties.AutomatedOffense,
@ -501,7 +642,11 @@ def penalties_table(existing_cur, new_cur):
EFPenalties."When" EFPenalties."When"
FROM FROM
EFPenalties EFPenalties
""") """
if limit:
query += f" LIMIT {limit}"
existing_cur.execute(query)
rows = existing_cur.fetchall() rows = existing_cur.fetchall()
for row in rows: for row in rows:
@ -588,7 +733,7 @@ def penalties_table(existing_cur, new_cur):
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
""", (penalty_id, automated_offense, expires, evaded_offense, offender_name, offense, punisher_name, penalty_type, timestamp)) """, (penalty_id, automated_offense, expires, evaded_offense, offender_name, offense, punisher_name, penalty_type, timestamp))
def penalty_Identifiers_table(existing_cur, new_cur): def penalty_identifiers_table(existing_cur, new_cur, limit=None):
new_cur.execute(""" new_cur.execute("""
CREATE TABLE "PenaltyIdentifiers" ( CREATE TABLE "PenaltyIdentifiers" (
"PenaltyIdentifierId" INTEGER NOT NULL, "PenaltyIdentifierId" INTEGER NOT NULL,
@ -598,7 +743,7 @@ def penalty_Identifiers_table(existing_cur, new_cur):
) )
""") """)
existing_cur.execute(""" query = """
SELECT SELECT
EFPenaltyIdentifiers.PenaltyIdentifierId, EFPenaltyIdentifiers.PenaltyIdentifierId,
EFPenaltyIdentifiers.PenaltyId, EFPenaltyIdentifiers.PenaltyId,
@ -606,7 +751,11 @@ def penalty_Identifiers_table(existing_cur, new_cur):
EFPenaltyIdentifiers.NetworkId EFPenaltyIdentifiers.NetworkId
FROM FROM
EFPenaltyIdentifiers EFPenaltyIdentifiers
""") """
if limit:
query += f" LIMIT {limit}"
existing_cur.execute(query)
rows = existing_cur.fetchall() rows = existing_cur.fetchall()
for row in rows: for row in rows:
@ -643,7 +792,7 @@ def penalty_Identifiers_table(existing_cur, new_cur):
VALUES (?, ?, ?, ?) VALUES (?, ?, ?, ?)
""", (penalty_identifier_id, penalty_id, created, client_name)) """, (penalty_identifier_id, penalty_id, created, client_name))
def servers_table(existing_cur, new_cur): def servers_table(existing_cur, new_cur, limit=None):
new_cur.execute(""" new_cur.execute("""
CREATE TABLE "Servers" ( CREATE TABLE "Servers" (
"ServerId" INTEGER NOT NULL, "ServerId" INTEGER NOT NULL,
@ -656,10 +805,14 @@ def servers_table(existing_cur, new_cur):
) )
""") """)
existing_cur.execute(""" query = """
SELECT ServerId, Active, Port, Endpoint, GameName, HostName, IsPasswordProtected SELECT ServerId, Active, Port, Endpoint, GameName, HostName, IsPasswordProtected
FROM EFServers FROM EFServers
""") """
if limit:
query += f" LIMIT {limit}"
existing_cur.execute(query)
rows = existing_cur.fetchall() rows = existing_cur.fetchall()
game_mapping = {5: "WaW", 7: "BO2", 6: "BO", 3: "MW3"} game_mapping = {5: "WaW", 7: "BO2", 6: "BO", 3: "MW3"}
@ -689,42 +842,5 @@ def servers_table(existing_cur, new_cur):
) VALUES (?, ?, ?, ?, ?, ?, ?) ) VALUES (?, ?, ?, ?, ?, ?, ?)
""", (server_id, active, port, endpoint, game_name, server_name, password)) """, (server_id, active, port, endpoint, game_name, server_name, password))
def inbox_messages_table(existing_cur, new_cur):
new_cur.execute("""
CREATE TABLE InboxMessagesModified (
InboxMessageId INTEGER PRIMARY KEY,
Created TEXT,
Origin TEXT,
Target TEXT,
ServerId INTEGER,
Message TEXT,
Read TEXT
)
""")
existing_cur.execute("SELECT * FROM InboxMessages")
inbox_messages = existing_cur.fetchall()
for msg in inbox_messages:
msg_id, created, _, source_client_id, dest_client_id, server_id, message, is_delivered = msg
for client_id in (source_client_id, dest_client_id):
existing_cur.execute("SELECT CurrentAliasId FROM EFClients WHERE ClientId = ?", (client_id,))
alias_id = existing_cur.fetchone()[0]
existing_cur.execute("SELECT Name FROM EFAlias WHERE AliasId = ?", (alias_id,))
name = existing_cur.fetchone()[0].replace('^7', '')
if client_id == source_client_id:
origin = name
else:
target = name
read = "Yes" if is_delivered == 1 else "No"
new_cur.execute("""
INSERT INTO InboxMessagesModified (InboxMessageId, Created, Origin, Target, ServerId, Message, Read)
VALUES (?, ?, ?, ?, ?, ?, ?)
""", (msg_id, created, origin, target, server_id, message, read))
if __name__ == '__main__': if __name__ == '__main__':
main() main()