websocket support
This commit is contained in:
parent
9230b1b785
commit
a2ad80303d
96
AOsocket.py
Normal file
96
AOsocket.py
Normal file
@ -0,0 +1,96 @@
|
||||
import socket
|
||||
import platform
|
||||
|
||||
import websocket
|
||||
|
||||
from game_version import *
|
||||
|
||||
|
||||
class AOtcpSocket(object):
|
||||
def __init__(self):
|
||||
self.sock = socket.socket()
|
||||
self.isWS = False
|
||||
|
||||
def connect(self, ip, port):
|
||||
try:
|
||||
self.sock.connect((ip, port))
|
||||
except:
|
||||
return False
|
||||
|
||||
self.sock.settimeout(0.1)
|
||||
return True
|
||||
|
||||
def recv(self):
|
||||
tempdata = ""
|
||||
gotIt = False
|
||||
while not gotIt:
|
||||
try:
|
||||
contents = self.sock.recv(16384)
|
||||
except (socket.timeout, socket.error) as err:
|
||||
error = err.args[0]
|
||||
if error == "timed out" or error == 10035 or err.errno == 11:
|
||||
return -2, []
|
||||
else: # connection lost
|
||||
return -1, []
|
||||
|
||||
if not contents.endswith("%"):
|
||||
tempdata += contents
|
||||
continue
|
||||
else:
|
||||
gotIt = True
|
||||
if tempdata:
|
||||
contents = tempdata + contents
|
||||
tempdata = ""
|
||||
|
||||
totals = contents.split('%')
|
||||
del totals[-1]
|
||||
for i in range(len(totals)):
|
||||
totals[i] = totals[i].split("#")
|
||||
del totals[i][-1]
|
||||
|
||||
return 0, totals
|
||||
|
||||
def send(self, data):
|
||||
return self.sock.send(data)
|
||||
|
||||
def close(self):
|
||||
self.sock.close()
|
||||
|
||||
class AOwebSocket(object):
|
||||
def __init__(self):
|
||||
self.sock = websocket.WebSocket()
|
||||
self.isWS = True
|
||||
self.header = {
|
||||
"User-Agent": "AO2XP %s, Python %s, %s %s %s %s %s" % (GAME_VERSION, platform.python_version(), platform.system(), platform.release(), platform.version(), platform.machine(), platform.processor())
|
||||
}
|
||||
|
||||
def connect(self, ip, port):
|
||||
try:
|
||||
self.sock.connect("ws://%s:%s" % (ip, port), header=self.header)
|
||||
except:
|
||||
return False
|
||||
|
||||
self.sock.settimeout(0.1)
|
||||
return True
|
||||
|
||||
def recv(self):
|
||||
try:
|
||||
contents = self.sock.recv()
|
||||
except websocket.WebSocketTimeoutException:
|
||||
return -2, []
|
||||
except websocket.WebSocketConnectionClosedException:
|
||||
return -1, []
|
||||
|
||||
totals = contents.split('%')
|
||||
del totals[-1]
|
||||
for i in range(len(totals)):
|
||||
totals[i] = totals[i].split("#")
|
||||
del totals[i][-1]
|
||||
|
||||
return 0, totals
|
||||
|
||||
def send(self, data):
|
||||
return self.sock.send(str(data))
|
||||
|
||||
def close(self):
|
||||
self.sock.close()
|
37
gameview.py
37
gameview.py
@ -1,4 +1,4 @@
|
||||
import socket, thread, time, os, buttons, urllib, charselect, ini, random
|
||||
import thread, time, os, buttons, urllib, charselect, ini, random
|
||||
from os.path import exists
|
||||
from ConfigParser import ConfigParser
|
||||
|
||||
@ -6,6 +6,7 @@ from pybass_constants import *
|
||||
from PyQt4 import QtGui, QtCore
|
||||
from functools import partial
|
||||
|
||||
import AOsocket
|
||||
import images
|
||||
|
||||
AOpath = "base/"
|
||||
@ -2486,7 +2487,6 @@ class gui(QtGui.QWidget):
|
||||
self.soundslider.setValue(ini.read_ini_int("AO2XP.ini", "Audio", "Sound volume", 100))
|
||||
self.blipslider.setValue(ini.read_ini_int("AO2XP.ini", "Audio", "Blip volume", 100))
|
||||
|
||||
self.tcp.settimeout(0.1)
|
||||
#thread.start_new_thread(self.tcp_thread, ())
|
||||
self.tcpthread = TCP_Thread(self)
|
||||
self.tcpthread.MS_Chat.connect(self.netmsg_ms)
|
||||
@ -2748,37 +2748,18 @@ class TCP_Thread(QtCore.QThread):
|
||||
self.parent.tcp.send(self.parent.msgqueue[0])
|
||||
sendtick = 4
|
||||
|
||||
try:
|
||||
contents = self.parent.tcp.recv(8192)
|
||||
except (socket.timeout, socket.error) as err:
|
||||
error = err.args[0]
|
||||
if error == "timed out" or error == 10035:
|
||||
continue
|
||||
else:
|
||||
self.parent.emit(QtCore.SIGNAL('showMessage(QString, QString, QString)'), 'critical', 'Connection lost', str(err))
|
||||
self.parent.willDisconnect = True
|
||||
self.quit()
|
||||
return
|
||||
|
||||
if not contents:
|
||||
self.parent.emit(QtCore.SIGNAL('showMessage(QString, QString, QString)'), 'critical', 'Connection lost', 'the server closed the connection')
|
||||
error, total = self.parent.tcp.recv()
|
||||
if error == -2:
|
||||
continue
|
||||
elif error == -1:
|
||||
self.parent.emit(QtCore.SIGNAL('showMessage(QString, QString, QString)'), 'critical', 'Connection lost', "%s connection to server lost." % ("WebSocket" if self.parent.tcp.isWS else "TCP"))
|
||||
self.parent.willDisconnect = True
|
||||
self.quit()
|
||||
return
|
||||
|
||||
if not contents.endswith("%"):
|
||||
tempdata += contents
|
||||
continue
|
||||
else:
|
||||
if tempdata:
|
||||
contents = tempdata + contents
|
||||
tempdata = ""
|
||||
|
||||
total = contents.split('%')
|
||||
for msg in total:
|
||||
network = msg.split('#')
|
||||
for network in total:
|
||||
header = network[0]
|
||||
del network[-1]
|
||||
#del network[-1]
|
||||
if header == 'MS':
|
||||
if len(network) < 15:
|
||||
print '[warning]', 'malformed/incomplete MS#chat (IC chat) network message was received'
|
||||
|
80
mainmenu.py
80
mainmenu.py
@ -1,10 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import socket, thread, time, random, traceback, requests, json
|
||||
import thread, time, random, traceback, requests, json
|
||||
from os.path import exists
|
||||
|
||||
from PyQt4 import QtGui, QtCore
|
||||
|
||||
import hardware
|
||||
import AOsocket
|
||||
from game_version import *
|
||||
|
||||
AOpath = "base/"
|
||||
@ -199,10 +200,11 @@ class lobby(QtGui.QWidget):
|
||||
desc = server["description"]
|
||||
ip = server["ip"]
|
||||
port = server["port"]
|
||||
ws_port = server["ws_port"] if "ws_port" in server else 0
|
||||
|
||||
serveritem = QtGui.QListWidgetItem(name)
|
||||
if self.tab == 0: self.serverlist.addItem(serveritem)
|
||||
self.actual_serverlist.append((ip, port, name, desc))
|
||||
self.actual_serverlist.append((ip, port, name, desc, ws_port))
|
||||
|
||||
def moveToGame(self, stuff):
|
||||
tcp, charlist, musiclist, background, evidence, areas, features, joinooc, hplist, webAO_bucket = stuff
|
||||
@ -315,8 +317,8 @@ class lobby(QtGui.QWidget):
|
||||
if self.serverlist.item(i) == item:
|
||||
if self.tab == 0:
|
||||
self.serverinfo.setText(self.actual_serverlist[i][3])
|
||||
self.aoserverinfo.setIP(text, *self.actual_serverlist[i][:2])
|
||||
print '[debug]', 'ind: ' + str(i) + ', ip: ' + self.actual_serverlist[i][0] + ', port: ' + str(self.actual_serverlist[i][1])
|
||||
self.aoserverinfo.setIP(text, self.actual_serverlist[i][0], self.actual_serverlist[i][1], self.actual_serverlist[i][-1])
|
||||
print '[debug]', 'ind: ' + str(i) + ', ip: ' + self.actual_serverlist[i][0] + ', port: ' + str(self.actual_serverlist[i][1]) + ", websocket port: " + str(self.actual_serverlist[i][-1])
|
||||
elif self.tab == 1:
|
||||
self.aoserverinfo.setIP(text, *self.favoriteslist[i][:2])
|
||||
print '[debug]', 'ind: ' + str(i) + ', ip: ' + self.favoriteslist[i][0] + ', port: ' + str(self.favoriteslist[i][1])
|
||||
@ -417,13 +419,16 @@ class AOServerInfo(QtCore.QThread):
|
||||
super(AOServerInfo, self).__init__()
|
||||
self.ip = ""
|
||||
self.port = 0
|
||||
self.ws_port = 0
|
||||
self.name = "jm"
|
||||
self.webAO_bucket = ""
|
||||
self.useWS = False
|
||||
self.disconnect = False
|
||||
|
||||
def setIP(self, name, ip, port):
|
||||
def setIP(self, name, ip, port, ws_port=0):
|
||||
self.ip = ip
|
||||
self.port = int(port)
|
||||
self.ws_port = int(ws_port)
|
||||
self.name = name
|
||||
|
||||
def stop(self):
|
||||
@ -434,15 +439,24 @@ class AOServerInfo(QtCore.QThread):
|
||||
|
||||
def run(self):
|
||||
self.disconnect = False
|
||||
self.tcp = socket.socket()
|
||||
self.tcp = AOsocket.AOwebSocket()
|
||||
try:
|
||||
self.tcp.connect((self.ip, self.port))
|
||||
if self.ws_port == 0: raise Exception # make it jump to except: and use TCP
|
||||
print "[debug]", "trying websocket..."
|
||||
self.tcp.connect(self.ip, self.ws_port)
|
||||
except:
|
||||
self.setOnlinePlayers.emit("couldn't retrieve players")
|
||||
return
|
||||
self.tcp.settimeout(0.2)
|
||||
self.tcp = AOsocket.AOtcpSocket()
|
||||
try:
|
||||
print "[debug]", "trying TCP..."
|
||||
self.tcp.connect(self.ip, self.port)
|
||||
except:
|
||||
self.setOnlinePlayers.emit("couldn't retrieve players")
|
||||
return
|
||||
|
||||
tempdata = ""
|
||||
print "[debug]", "connected! websocket: %s" % self.tcp.isWS
|
||||
self.tcp.sock.settimeout(0.1)
|
||||
|
||||
got_stuff = False
|
||||
gotChars = False
|
||||
hplist = []
|
||||
joinooc = []
|
||||
@ -477,27 +491,14 @@ class AOServerInfo(QtCore.QThread):
|
||||
self.setWindowTitle.emit("AO2XP: "+self.name)
|
||||
return
|
||||
|
||||
try:
|
||||
contents = self.tcp.recv(16384)
|
||||
except (socket.timeout, socket.error) as err:
|
||||
error = err.args[0]
|
||||
if error == "timed out" or error == 10035:
|
||||
continue
|
||||
else:
|
||||
self.setOnlinePlayers.emit("Something wrong happened" if not got_stuff else "Connection lost")
|
||||
return
|
||||
|
||||
if not contents.endswith("%"):
|
||||
tempdata += contents
|
||||
error, totals = self.tcp.recv()
|
||||
if error == -2: # timeout
|
||||
continue
|
||||
else:
|
||||
if tempdata:
|
||||
contents = tempdata + contents
|
||||
tempdata = ""
|
||||
elif error == -1: # disconnected
|
||||
self.setOnlinePlayers.emit("Something wrong happened" if not got_stuff else "Connection lost")
|
||||
return
|
||||
|
||||
totals = contents.split('%')
|
||||
for g in totals:
|
||||
network = g.split('#')
|
||||
for network in totals:
|
||||
header = network[0]
|
||||
|
||||
if header == 'PN':
|
||||
@ -543,7 +544,6 @@ class AOServerInfo(QtCore.QThread):
|
||||
if self.disconnect:
|
||||
continue
|
||||
del network[0]
|
||||
del network[len(network)-1]
|
||||
gotChars = True
|
||||
charlist = [ [char.split('&')[0], 0, "male"] for char in network ]
|
||||
self.setConnectProgress.emit('Requesting music list (%d)...' % maxmusic)
|
||||
@ -554,7 +554,6 @@ class AOServerInfo(QtCore.QThread):
|
||||
if self.disconnect:
|
||||
continue
|
||||
del network[0]
|
||||
del network[len(network)-1]
|
||||
|
||||
musiclist = [music for music in network]
|
||||
|
||||
@ -565,8 +564,7 @@ class AOServerInfo(QtCore.QThread):
|
||||
elif header == 'CharsCheck':
|
||||
if self.disconnect or not gotChars:
|
||||
continue
|
||||
network.pop(0)
|
||||
network.pop(len(network)-1)
|
||||
del network[0]
|
||||
for i in range(len(network)):
|
||||
charlist[i][1] = int(network[i])
|
||||
|
||||
@ -580,7 +578,6 @@ class AOServerInfo(QtCore.QThread):
|
||||
if self.disconnect:
|
||||
continue
|
||||
del network[0]
|
||||
del network[len(network)-1]
|
||||
if len(network) > 0:
|
||||
evidence = [evi.split("&") for evi in network]
|
||||
else:
|
||||
@ -597,15 +594,12 @@ class AOServerInfo(QtCore.QThread):
|
||||
elif header == 'HP':
|
||||
if self.disconnect:
|
||||
continue
|
||||
del network[0]
|
||||
del network[len(network)-1]
|
||||
type = int(network[0])
|
||||
health = int(network[1])
|
||||
type = int(network[1])
|
||||
health = int(network[2])
|
||||
hplist.append([type, health])
|
||||
|
||||
elif header == "ARUP": #AO2 2.6 new feature: area update
|
||||
del network[0]
|
||||
del network[len(network)-1]
|
||||
type = int(network[0])
|
||||
if type == 0: #player count
|
||||
areas[type] = [network[i] for i in range(1, len(network))]
|
||||
@ -623,8 +617,6 @@ class AOServerInfo(QtCore.QThread):
|
||||
elif header == 'CT':
|
||||
if self.disconnect:
|
||||
continue
|
||||
del network[0]
|
||||
del network[len(network)-1]
|
||||
name = network[0].decode("utf-8").replace('<dollar>', '$').replace('<percent>', '%').replace('<and>', '&').replace('<num>', '#').replace('<pound>', '#')
|
||||
chatmsg = network[1].decode("utf-8").replace('<dollar>', '$').replace('<percent>', '%').replace('<and>', '&').replace('<num>', '#').replace('<pound>', '#')
|
||||
name = network[1].decode("utf-8").replace('<dollar>', '$').replace('<percent>', '%').replace('<and>', '&').replace('<num>', '#').replace('<pound>', '#')
|
||||
chatmsg = network[2].decode("utf-8").replace('<dollar>', '$').replace('<percent>', '%').replace('<and>', '&').replace('<num>', '#').replace('<pound>', '#')
|
||||
joinooc.append("%s: %s" % (name, chatmsg))
|
@ -6,11 +6,11 @@ import os
|
||||
import platform
|
||||
|
||||
def pip_install(*args):
|
||||
print "installing " + ", ".join(args)
|
||||
command = [sys.executable, "-m", "pip", "install"]
|
||||
command.extend(args)
|
||||
subprocess.call(command)
|
||||
|
||||
print "installing requests"
|
||||
pip_install('requests')
|
||||
import requests
|
||||
|
||||
@ -72,7 +72,6 @@ zip_ref = zipfile.ZipFile(BASSOPUSZIP, 'r')
|
||||
zip_ref.extract(BASSOPUSDLL)
|
||||
zip_ref.close()
|
||||
|
||||
print "installing apng, six, appdirs, packaging"
|
||||
pip_install("apng", "six", "appdirs", "packaging")
|
||||
|
||||
try:
|
||||
@ -80,17 +79,15 @@ try:
|
||||
if Image.__version__ != "5.3.0":
|
||||
jm = raw_input("Pillow version 5.3.0 is recommended for compatibility with AO2XP; You have version %s\nReplace with version 5.3.0? (Y/N) > " % Image.__version__).lower()
|
||||
if jm == "y":
|
||||
print "installing Pillow 5.3.0"
|
||||
pip_install("Pillow==5.3.0")
|
||||
else:
|
||||
print "Pillow 5.3.0 already exists, skipping"
|
||||
|
||||
except ImportError:
|
||||
print "installing Pillow 5.3.0"
|
||||
pip_install("Pillow==5.3.0")
|
||||
|
||||
print "installing pyinstaller"
|
||||
pip_install('pyinstaller==3.6')
|
||||
pip_install("websocket-client")
|
||||
|
||||
if platform.system() == "Windows":
|
||||
print "downloading pyqt4"
|
||||
|
Loading…
Reference in New Issue
Block a user