Author | Message | Time |
---|---|---|
squeegee | I can't log into Warrior's FTP right now, so here it is: pwcb.py [code]import pbuffer import winamp import pcap import dpkt """(Python) Winamp Controller for Battle.net""" __version__ = "1.0.0" __author__ = "topaz" __copyright__ = "modified BSD license" class pwcb: def __init__(self, port=6112, verbose=True): self.port = port self.verbose = verbose self.pcap = pcap.pcap() self.pcap.setfilter("tcp") self.ip = "" self.winamp = winamp.winamp() self.buffer_data = "" self.buffer_length = 0 def begin_capture(self): for t, pkt in self.pcap: stream = dpkt.ethernet.Ethernet(pkt) data = stream.data.data self.ip = "%d.%d.%d.%d" %tuple(map(ord, list(stream.data.dst))) if data.dport == self.port: self.process_stream(data) def process_stream(self, data): if data.data != "": recv_buffer = pbuffer.recv_buffer(data.data) while recv_buffer.position < len(data.data): if recv_buffer.next_byte() <> 0xFF: return packet_id = recv_buffer.next_byte() packet_length = recv_buffer.next_word() if packet_id == 0x0E: s = recv_buffer.next_string() self.process_cmd(s) recv_buffer.position = recv_buffer.position + packet_length def process_cmd(self, data): if data[0] == "/": data = data[1:] cmd = data.split(" ")[0] if cmd == "play": if len(data.split(" ")) == 1: self.winamp.play() self.notify("Winamp has begun playing.") else: song_title = " ".join(data.split(" ")[1:]) self.winamp.play(song_title) elif cmd == "execute": self.winamp.execute() self.notify("Winamp has been opened.") elif cmd == "setvol": vol = int(data.split(" ")[1]) self.winamp.set_vol(vol) self.notify("Winamp's volume has been set to %d." %vol) elif cmd == "next": self.winamp.next() self.notify("Winamp has skipped to the next song.") elif cmd == "previous": self.winamp.previous() self.notify("Winamp is skipping to the previous song.") elif cmd == "close": self.winamp.close() self.notify("Winamp has been closed.") elif cmd == "stop": self.winamp.stop() self.notify("Winamp has been stopped.") elif cmd == "pause": self.winamp.pause() self.notify("Winamp has been paused/unpaused.") def notify(self, text): if self.verbose == True: print text def about(self): print "(Python) Winamp Controller for Battle.net\n" print "-- You will require the following items if this program was not included as an executable;" print "-- Python 2.5 or above installed on your machine," print "-- the WinPcap port for Windows installed," print "-- the pypcap package (written by Dug Song) installed," print "-- and the dpkt package (also written by Dug Song) installed.\n" print "-- PWCB was begun on 11 April of 2007." print "Welcome to the (Python) Winamp Controller for Battle.net!\n" p = pwcb() p.notify("Beginning packet capture for port 6112.") p.begin_capture()[/code] winamp.py [code]__version__ = '1.1.0' __author__ = 'topaz' __copyright__ = 'modified BSD License' import win32api import win32gui import time import os WM_COMMAND = 0x400 WM_MSG = 273 class winamp: def __init__(self): try: self.get_handle() except Exception, error: print "Winamp does not appear to be open; executing now.\n" self.execute() time.sleep(1.5) self.get_handle() def get_handle(self): return win32gui.FindWindow('Winamp v1.x', None) def execute(self): os.startfile('C:\Program Files\Winamp\winamp.exe') def play(self, song_title=""): if song_title == "": win32api.SendMessage(self.get_handle(), WM_MSG, 40045, 0) else: win32api.PostMessage(self.get_handle(), WM_MSG, 40194, 0) while True: win32gui.PumpWaitingMessages() jumpto = win32gui.FindWindow('#32770', "Jump to file") edit = win32gui.FindWindowEx(jumpto, 0, 'Edit', None) listbox = win32gui.FindWindowEx(jumpto, 0, 'ListBox', None) if listbox != 0: break win32gui.SendMessage(edit, 0x0C, 0, song_title) if win32api.SendMessage(listbox, 0x18B, 0, 0) == 0: win32api.PostMessage(jumpto, 0x10, 0, 0) else: win32api.SendMessage(listbox, 0x203, 0, 0) def set_vol(self, volume): win32api.SendMessage(self.get_handle(), WM_COMMAND, int(volume * 2.55), 122) def next(self): win32api.SendMessage(self.get_handle(), WM_MSG, 40048, 0) def previous(self): win32api.SendMessage(self.get_handle(), WM_MSG, 40044, 0) def close(self): win32api.SendMessage(self.get_handle(), WM_MSG, 40001, 0) def stop(self): win32api.SendMessage(self.get_handle(), WM_MSG, 40047, 0) def pause(self): #used for both pausing and unpausing win32api.SendMessage(self.get_handle(), WM_MSG, 40046, 0) def song(self): return win32gui.GetWindowText(self.get_handle())[:-9] def bitrate(self): return win32api.SendMessage(self.get_handle(), WM_COMMAND, 1, 126) def play_status(self): """0 = stopped, 1 = playing, 3 = paused""" return win32api.SendMessage(self.get_handle(), WM_COMMAND, 0, 104)[/code] pbuffer.py [code]import struct def unpack_dword(data): return struct.unpack('I', data)[0] def unpack_word(data): return struct.unpack('H', data)[0] def unpack_byte(data): return struct.unpack('<B', data)[0] class recv_buffer: def __init__(self, raw_buffer): self.raw_buffer = raw_buffer self.position = 0 def jump(self, bytes): self.position += bytes def back(self, bytes): self.position -= bytes def set_position(self, position): self.position = position def next_string(self): pos = self.raw_buffer.find(chr(0), self.position) string = self.raw_buffer[self.position:pos] self.set_position(pos + 1) return string def next_byte(self): param = self.raw_buffer[self.position:self.position + 1] byte = unpack_byte(param) self.jump(1) return byte def next_dword(self): param = self.raw_buffer[self.position:self.position + 4] dword = unpack_dword(param) self.jump(4) return dword def next_word(self): param = self.raw_buffer[self.position:self.position + 2] word = unpack_word(param) self.jump(2) return word def next_dword_list(self, size): dword_list = [] for i in xrange(size): dword_list.append(self.next_dword()) return dword_list def dump_data(self): del self.raw_buffer[/code] Listens on port 6112 and reads streams, looking for commands to manipulate Winamp. Only works with Winamp, but itunes/fb2k/etc support could be added if you cared. Only tested on wc3 and w2bn, idk about utf-8 junk on starcraft that could mess with how data is processed. Run pwcb.py in console or in a shell and it'll do the rest. Requires pypcap, dpkt, WinPcap, and Python to be installed. | July 5, 2007, 2:01 AM |
raylu | You should have mentioned that this simply hooked onto an existing connection. Essentially, a packet sniffer. If you're only listening for certain commands, UTF-8 will not affect those commands (they are in English and use only standard alphanumeric characters). | July 5, 2007, 2:40 AM |
squeegee | "Listens on port 6112" kind of says that right off the bat, and the use of WinPcap also tells you that Good work captain | July 5, 2007, 2:42 AM |
Myndfyr | [quote author=squeegee link=topic=16849.msg170728#msg170728 date=1183603351] "Listens on port 6112" kind of says that right off the bat [/quote] Actually no, "listens on port 6112" means that it opens a socket on that port and waits until it receives an incoming connection.... | July 5, 2007, 5:02 PM |
raylu | I skimmed over the requirements, like most people. I just wanted to see what it did and found no information about this. Usage of 6112 says either that or shows that the person who made it chose to use the same port as B.net. Stupid, but not totally unreasonable. | July 6, 2007, 3:01 AM |
squeegee | You're not going to cry about it, are you? | July 6, 2007, 8:20 PM |
bethra | The creator of this topic sure knows how to ask for help. | July 6, 2007, 11:28 PM |
squeegee | Does it look like I asked for help? | July 7, 2007, 12:04 AM |
warz | Just another completely useless program, written by mr. topaz. | July 7, 2007, 4:47 AM |
squeegee | K, gimme a sec to spend eight months reversing something only to write a trivial non-fix Oh wait sry. | July 7, 2007, 6:45 AM |
squeegee | This script is cool, okay? Don't be jealous | July 7, 2007, 7:55 AM |