User:Darqam/Python Id Script

From Guild Wars 2 Wiki
Jump to navigationJump to search

Intro[edit]

Heya, so this page will hold the script(s) I use to type out the ids of items in the game client. This operates similarly to what that_shaman shows here. Although built by myself, I used his idea to make it.

Required Installs[edit]

This script runs off python 3+, and will bug out in 2.7 (but could be fixed if someone cared). A portion of the script selects the GW2 window but for that you will need pywin32. If you don't have it, comment out the required block of code and manually select the GW2 window after you've launched the script.

I also make use of pyautogui so install that.

Functionality[edit]

While this code is running, make sure not to interact with the game, or swap to another window. If you close the dialogue box, the script will keep hitting letters and hell if I know what that will do to your keybinds. If you focus on another window without killing the script, it will keep typing, again hell if I know what that will do depending on your shortcuts.

If you DO NOT HAVE pywin32, the second you start the script, immediately select the GW2 window. You may want to add an initial "time.sleep(2)" to give you two seconds to select the GW2 window.

When you start this script PLEASE ensure that you are not spamming say chat or map chat. Ideally create a squad and have your chat setup to talk in there. A good place to AFK with a tag up is either in a raid instance, or in the aerodrome. No one cares about an AFK tag there.

To launch this script, go to you command prompt window, navigate to the proper folder where BOTH THESE FILES ARE SAVED. Type in: "python write_id.py" (without quotation marks), and let it do its thing

Changing the settings[edit]

The lines you should most care about are in the write_id.py file, lines 32, 34, and 37.

  • Line 32: start_id This variable is an integer which represents the first id which will be checked by the script. This variable does not care what the id is used for, only that it is a number.
  • line 34: total_check This variable lists how many ids will be checked with this iteration of the script. For example if start_id = 25 and total_check = 2, you will get the chat codes for id 25, and id 26.
  • line 37: select This variable will choose what type of id you are looking at. By selecting the proper number (shown in the commend beside it) you will tell the script what type of chat code it is outputting.

Files[edit]

write_id.py[edit]

#this import line brings things for the second file (default name key_define.py)
from key_define import PressKey, ReleaseKey

import pyautogui, time, random
import binascii, base64, struct
##### 
#Script written by Darqam, mini-documentation at https://wiki.guildwars2.com/wiki/User:Darqam/Python_Id_Script
#####

#if you do not have pywin32 installed remove what is between these lines
##############
import win32com.client as comclt
wsh= comclt.Dispatch("WScript.Shell")
wsh.AppActivate("Guild Wars 2") # select GW2 application
##############

typing_speed = 50 #wpm
def slow_type(t):
	for l in t:
		pyautogui.typewrite(l)
		time.sleep(random.random()*10.0/typing_speed)#random pauses make it seem like more "human" writing

def hit_enter(): #because typing this is way faster than those 4 lines
	time.sleep(0.5)
	PressKey(0x1c) #pushes down the return("enter") key
	ReleaseKey(0x1c) #releases the return key (necessary or else you can't press it again)
	time.sleep(0.5) #small delay to give time for game to interpret key strokes
		
debug = False
	
#items: 79701, maps: 2424, outfits: 41
start_id = 100 #this is the ID number where the program will start, check https://api.guildwars2.com/v2 to see where the last id are (for some cases)

total_check = 2 #Total amount of ids that will be checked, including that listed in start_id

options = ["outfits", "items", "wardrobe", "skills", "traits", "recipes", "maps", "test"] #list containing all the option for quicker selection change
select = options[7] #0=outfits, 1=items, 2=wardrobe, 3=skills, 4=traits, 5=recipes, 6=maps, 7=test

hex_id = ''#defining out of if statements
a = ''

for i in range(0,total_check):
	tmp = struct.unpack('<I',struct.pack('>I',start_id))[0]#'flips around' the hex values since GW2 does that
	hex_id = hex(tmp)[2:]#convert to hex and remove leading '0x'
	#constructing the start of the hex based off GW2 predefined values
	if select is "outfits":
		a = '0B'
	if select is "items":
		a = '0201'
	if select is "maps":
		a = '04'
	if select is "skills":
		a = '06'
	if select is "traits":
		a = '07'
	if select is "recipes":
		a = '09'
	if select is "wardrobe":
		a = '0A'
	if select is "test":
		a = '01'
	#The goal here is to construct a full hex string to then base64 encode
	hex_string = a+hex_id#merge the hex string into one
	hex_string = hex_string.ljust(10,'0')#add 0s at the end until string is 10 characters long
	
	if debug is True:
		print(len(hex_string))
		print(hex_string)
	
	#next few lines will encode the string into base64 and format it properly for python\output use
	bin_string = binascii.unhexlify(hex_string) 
	base = base64.b64encode(bin_string)
	base = base.decode("utf-8")
	#print(base)
	
	#format the output to be printed
	tot_string = '[&'+base+']'
	output = 'ID = '+str(start_id)+': '+tot_string
	
	if debug is True:
		print(output)
	if debug is False:
		time.sleep(1) #1 second delay between all outputs
		hit_enter()
		slow_type(output) #type out the output
		hit_enter()

	start_id += 1
if debug is False:
	hit_enter()
	slow_type("All done!")
	hit_enter()

key_define.py[edit]

##############
#This code is taken from: http://stackoverflow.com/questions/14489013/simulate-python-keypresses-for-controlling-a-game
##############
import ctypes
import time

SendInput = ctypes.windll.user32.SendInput

# C struct redefinitions 
PUL = ctypes.POINTER(ctypes.c_ulong)
class KeyBdInput(ctypes.Structure):
    _fields_ = [("wVk", ctypes.c_ushort),
                ("wScan", ctypes.c_ushort),
                ("dwFlags", ctypes.c_ulong),
                ("time", ctypes.c_ulong),
                ("dwExtraInfo", PUL)]

class HardwareInput(ctypes.Structure):
    _fields_ = [("uMsg", ctypes.c_ulong),
                ("wParamL", ctypes.c_short),
                ("wParamH", ctypes.c_ushort)]

class MouseInput(ctypes.Structure):
    _fields_ = [("dx", ctypes.c_long),
                ("dy", ctypes.c_long),
                ("mouseData", ctypes.c_ulong),
                ("dwFlags", ctypes.c_ulong),
                ("time",ctypes.c_ulong),
                ("dwExtraInfo", PUL)]

class Input_I(ctypes.Union):
    _fields_ = [("ki", KeyBdInput),
                 ("mi", MouseInput),
                 ("hi", HardwareInput)]

class Input(ctypes.Structure):
    _fields_ = [("type", ctypes.c_ulong),
                ("ii", Input_I)]

# Actuals Functions

def PressKey(hexKeyCode):
    extra = ctypes.c_ulong(0)
    ii_ = Input_I()
    ii_.ki = KeyBdInput( 0, hexKeyCode, 0x0008, 0, ctypes.pointer(extra) )
    x = Input( ctypes.c_ulong(1), ii_ )
    ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))

def ReleaseKey(hexKeyCode):
    extra = ctypes.c_ulong(0)
    ii_ = Input_I()
    ii_.ki = KeyBdInput( 0, hexKeyCode, 0x0008 | 0x0002, 0, ctypes.pointer(extra) )
    x = Input( ctypes.c_ulong(1), ii_ )
    ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))

# directx scan codes http://www.gamespp.com/directx/directInputKeyboardScanCodes.html
#while (True):
    #PressKey(0x1c)
    #time.sleep(1)
    #ReleaseKey(0x1c)
    #time.sleep(1)