Greetings. I played solo, so I wanted a more realistic Central Market feel.
I decided to make a small program that will purchase all of my items off of the marketplace, for a percentage, and then mail me the proceeds.
1. Install python. I use 3.9.5 which is installed when you install Corsair.
2. Use Task Scheduler to call on this script as often as you like.
3. No need for players to be logged out. When they open the market, they will see what was sold but cannot interact with it. When they list anything, the list will update to show nothing but what they just listed.
4. Adjust the code to change the % that it mails the player.
5. This requires sendMail which can be found in my post, here, about the Central/Black Market that I made (about half way down the page is instructions on send mail.
NOTES:
1. TAX_RATE can be adjusted. This is what is deducted from the purchase.
2. Silver item key is used to tell what gets sent to the player.
3. Sender_User_No = 1 (This is the admin account that I use to populate the market. I dont want to purchase all of the default items. I will post how to fill up the market next).
I decided to make a small program that will purchase all of my items off of the marketplace, for a percentage, and then mail me the proceeds.
1. Install python. I use 3.9.5 which is installed when you install Corsair.
2. Use Task Scheduler to call on this script as often as you like.
3. No need for players to be logged out. When they open the market, they will see what was sold but cannot interact with it. When they list anything, the list will update to show nothing but what they just listed.
4. Adjust the code to change the % that it mails the player.
5. This requires sendMail which can be found in my post, here, about the Central/Black Market that I made (about half way down the page is instructions on send mail.
NOTES:
1. TAX_RATE can be adjusted. This is what is deducted from the purchase.
2. Silver item key is used to tell what gets sent to the player.
3. Sender_User_No = 1 (This is the admin account that I use to populate the market. I dont want to purchase all of the default items. I will post how to fill up the market next).
Python:
import pandas as pd
import pyodbc
import subprocess
import os
# --- Configuration ---
SERVER_TRADE = 'localhost'
DATABASE_TRADE = 'SA_BETA_TRADEDB_0002'
SERVER_WORLD = 'localhost'
DATABASE_WORLD = 'SA_BETA_WORLDDB_0002'
TAX_RATE = 0.15
SILVER_ITEM_KEY = 1
SENDER_USER_NO = 1
def get_users_with_market_items():
conn_str = f'DRIVER={{ODBC Driver 17 for SQL Server}};SERVER={SERVER_TRADE};DATABASE={DATABASE_TRADE};Trusted_Connection=yes'
with pyodbc.connect(conn_str) as conn:
cursor = conn.cursor()
cursor.execute("""
SELECT DISTINCT _userNo
FROM [PaGamePrivate].[TblWorldMarketBiddingSell]
WHERE _userNo != 1
""")
return [row[0] for row in cursor.fetchall()]
def purchase_and_mail_items(target_user_no):
cnxn_trade = None
cnxn_world = None
try:
# --- Connect to Trade DB ---
conn_str_trade = f'DRIVER={{ODBC Driver 17 for SQL Server}};SERVER={SERVER_TRADE};DATABASE={DATABASE_TRADE};Trusted_Connection=yes'
cnxn_trade = pyodbc.connect(conn_str_trade)
cursor_trade = cnxn_trade.cursor()
cnxn_trade.autocommit = False
print(f"\n--- Processing _userNo={target_user_no} ---")
print(f"Connected to Trade DB '{DATABASE_TRADE}'.")
select_query = """
SELECT _sellNo, _mainKey, _subKey, _leftCount, _pricePerOne
FROM [PaGamePrivate].[TblWorldMarketBiddingSell]
WHERE _userNo = ?;
"""
cursor_trade.execute(select_query, target_user_no)
items_to_process = cursor_trade.fetchall()
if not items_to_process:
print("No market items. Skipping.")
cnxn_trade.rollback()
return False
total_sale_value = 0
deleted_sell_nos = []
for item in items_to_process:
sell_no, main_key, sub_key, left_count, price_per_one = item
item_total = left_count * price_per_one
total_sale_value += item_total
deleted_sell_nos.append(sell_no)
print(f" - Item: {main_key}, Qty: {left_count}, Price: {price_per_one}, Total: {item_total}")
tax_amount = int(total_sale_value * TAX_RATE)
net_silver_to_send = total_sale_value - tax_amount
print(f" Total: {total_sale_value}, Tax: {tax_amount}, Net: {net_silver_to_send}")
delete_placeholders = ', '.join(['?'] * len(deleted_sell_nos))
delete_query = f"DELETE FROM [PaGamePrivate].[TblWorldMarketBiddingSell] WHERE _sellNo IN ({delete_placeholders});"
cursor_trade.execute(delete_query, *deleted_sell_nos)
cnxn_trade.commit()
print("Items deleted.")
if net_silver_to_send <= 0:
print("No silver to send. Skipping mail.")
return True
# --- Get user nickname ---
conn_str_world = f'DRIVER={{ODBC Driver 17 for SQL Server}};SERVER={SERVER_WORLD};DATABASE={DATABASE_WORLD};Trusted_Connection=yes'
cnxn_world = pyodbc.connect(conn_str_world)
cursor_world = cnxn_world.cursor()
cursor_world.execute("SELECT _userNickname FROM [PaGamePrivate].[TblUserInformation] WHERE _userNo = ?;", target_user_no)
row = cursor_world.fetchone()
if not row:
print("Nickname not found. Skipping mail.")
return False
nickname = row[0]
print(f"Sending {net_silver_to_send} silver to '{nickname}'...")
result = subprocess.call(["python", "Send_Mail.py", nickname, str(net_silver_to_send)])
if result != 0:
print(f"Send_Mail.py failed with code {result}")
return False
print("Mail sent.")
return True
except Exception as ex:
print("ERROR:", ex)
if cnxn_trade and not cnxn_trade.autocommit:
cnxn_trade.rollback()
return False
finally:
if cnxn_trade:
cnxn_trade.close()
if cnxn_world:
cnxn_world.close()
if __name__ == "__main__":
users = get_users_with_market_items()
print(f"Found {len(users)} users with items listed.\n")
for user_no in users:
purchase_and_mail_items(user_no)

