I have the following script, how to make it work on apache (I installed python server and all required configurations), now my problem is where i add def index(): i get error of indentation :(, you have solution for this problem ? and how to change:
port = 22
user = "user"
password = "password"
host = "127.0.0.1"
To $_GET ? (http://localhost/test.py?host=127.0.0.1&port=22&user=test&password=123)
import paramiko
import sys, os
import socket
import re
# - - - - - - - - - - - - - - - - #
# SSH Checker #
# - - - - - - - - - - - - - - - - #
#def index():
def is_work_sshd(host, dPort=22):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(20)
try:
sock.connect((host, dPort))
except:
return 1
sock.close()
return 0
def check_server(host, user, password, port=22):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#proxy = paramiko.ProxyCommand("127.0.0.1:8118")
if is_work_sshd(host,port): return 2
try:
ssh.connect(host, username=user, password=password, port=port)
ssh.close()
except:
return 1
return 0
def index():
port = 22
user = "user"
password = "password"
host = "127.0.0.1"
ret = check_server(host, user, password, port)
if not ret:
return "CONNECT"
elif ret == 1:
return "FAILED"
else:
return "FAILED"
Error message:
root#www:/var/www# python t.py
File "t.py", line 49
ret = check_server(host, user, password, port)
^
You should add def index(): before the line port = 22:
return 0
def index():
return "<html><body>Hello, world.</body></html>"
port = 22
Note: In Python, indentation is part of the syntax. So make sure you indent properly and correctly. See also https://docs.python.org/2/tutorial/introduction.html#first-steps-towards-programming
make sure the code editor which you use always uses tabs or spaces for indenting and don't mix the two. Editors which show whitespace work well, editors which clean up indentation automatically for Python code are better.
EDIT Here is the correct code:
def check_server(host, user, password, port=22):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
#proxy = paramiko.ProxyCommand("127.0.0.1:8118")
if is_work_sshd(host,port): return 2
try:
ssh.connect(host, username=user, password=password, port=port)
ssh.close()
except:
return 1
return 0
def index():
port = 22
user = "user"
password = "password"
host = "127.0.0.1"
ret = check_server(host, user, password, port)
if not ret:
return "CONNECT"
elif ret == 1:
return "FAILED"
else:
return "FAILED"
Related
I am having a Pickle issue with SSL client to server communication using multiprocessing.
I have an SSL client that connects to the server:
SSLClient.py
import socket
import struct
import ssl
import copyreg
from os import path
import socket
import os
from pathlib import Path
from loguru import logger as log
from utils.misc import read_py_config
from datetime import datetime
from cryptography.fernet import Fernet
fernetkey = '1234567'
fernet = Fernet(fernetkey)
class SSLclient:
license = None
licenseencrypted = None
uuid = None
def __init__(self):
try:
path = Path(__file__).parent / "/lcl" #get unique license key
with path.open() as file:
self.licenseencrypted = file.read().rstrip()
self.license = fernet.decrypt(str.encode(self.licenseencrypted)).decode('ascii')
self.host, self.port = "127.0.0.1", 65416
except Exception as e:
log.error("Could not decode license key")
def connect(self):
self.client_crt = os.path.join(os.path.dirname(__file__), 'key/c-.crt')
self.client_key = os.path.join(os.path.dirname(__file__), 'key/ck-.key')
self.server_crt = os.path.join(os.path.dirname(__file__), 'key/s-.crt')
self.sni_hostname = "example.com"
self._context = ssl.create_default_context(ssl.Purpose.SERVER_AUTH, cafile=self.server_crt)
self._context.load_cert_chain(certfile=self.client_crt, keyfile=self.client_key)
self._sock = None
self._ssock = None
## ---- Client Communication Setup ----
HOST = self.host # The server's hostname or IP address
PORT = self.port # The port used by the server
try:
self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self._ssock = self._context.wrap_socket(self._sock, server_side=False, server_hostname=self.sni_hostname)
self._ssock.connect((HOST, PORT))
log.info("Socket successfully created")
except socket.error as err:
log.error("socket creation failed with error %s" %(err))
return False
log.info('Waiting for connection')
return True
def closesockconnection(self):
self._ssock.close()
def checkvalidsite(self):
#check if site is active
jsonobj = {
"uuid": self.license,
"ipaddress" : self.external_ip,
"req": "checkvalidsite"
}
send_msg(self._ssock, json.dumps(jsonobj).encode('utf-8'))
active = False
while True:
Response = recv_msg(self._ssock)
if not Response:
return False
if Response is not None:
Response = Response.decode('utf-8')
Response = json.loads(Response)
req = Response['req']
if req == "checkvalidsite":
active = Response['active']
self.info1 = Response['info1']
self.info2 = Response['info2']
return active
# ---- To Avoid Message Boundary Problem on top of TCP protocol ----
def send_msg(sock: socket, msg): # ---- Use this to send
try:
# Prefix each message with a 4-byte length (network byte order)
msg = struct.pack('>I', len(msg)) + msg
sock.sendall(msg)
except Exception as e:
log.error("Sending message " + str(e))
def recv_msg(sock: socket): # ---- Use this to receive
try:
# Read message length and unpack it into an integer
raw_msglen = recvall(sock, 4)
if not raw_msglen:
return None
msglen = struct.unpack('>I', raw_msglen)[0]
# Read the message data
return recvall(sock, msglen)
except Exception as e:
log.error("Receiving message " + str(e))
return False
def recvall(sock: socket, n: int):
try:
# Helper function to receive n bytes or return None if EOF is hit
data = bytearray()
while len(data) < n:
packet = sock.recv(n - len(data))
if not packet:
return None
data.extend(packet)
return data
except Exception as e:
log.error("Receiving all message " + str(e))
raise Exception(e)
I then have a server that is Multithreaded and accepts the connection and communicates with the client.
Server.py
import socket
import os
from socket import AF_INET, SOCK_STREAM, SO_REUSEADDR, SOL_SOCKET, SHUT_RDWR
import ssl
from os import path
from _thread import *
import struct # Here to convert Python data types into byte streams (in string) and back
import traceback
from threading import Thread
import json
import mysql.connector as mysql
import time
from loguru import logger as log
import threading
from cryptography.fernet import Fernet
fernetkey = '12213423423'
fernet = Fernet(fernetkey)
threadLocal = threading.local()
# ---- To Avoid Message Boundary Problem on top of TCP protocol ----
def send_msg(sock: socket, msg): # ---- Use this to send
try:
# Prefix each message with a 4-byte length (network byte order)
msg = struct.pack('>I', len(msg)) + msg
sock.sendall(msg)
except Exception as e:
log.error("Error send_msg " + str(e))
def recv_msg(sock: socket): # ---- Use this to receive
try:
# Read message length and unpack it into an integer
raw_msglen = recvall(sock, 4)
if not raw_msglen:
return None
msglen = struct.unpack('>I', raw_msglen)[0]
# Read the message data
return recvall(sock, msglen)
except Exception as e:
log.error("Receiving message " + str(e))
return False
def recvall(sock: socket, n: int):
try:
# Helper function to receive n bytes or return None if EOF is hit
data = bytearray()
while len(data) < n:
packet = sock.recv(n - len(data))
if not packet:
return None
data.extend(packet)
return data
except Exception as e:
log.error("Receiving all message " + str(e))
raise Exception(e)
# ---- Server Communication Setup
class Newclient:
def __init__(self):
self.addr = None
self.conn = None
self.uuid = None
class Server:
def __init__(self):
self.HOST = '127.0.0.1' # Standard loopback interface address (localhost)
self.PORT = 65416 # Port to listen on (non-privileged ports are > 1023)
self.ThreadCount = 0
self.threads = []
self.sock = None
def checkvalidsite(self, uuid, ipaddress, cursor, db_connection):
sql = "select * from myexample where uuid ='" + uuid + "'"
cursor.execute(sql)
results = cursor.fetchall()
active = False
for row in results:
active = row["active"]
siteid = row["info1"]
clientid = row["info2"]
return active, siteid, clientid
def Serverthreaded_client(self, newclient):
conn = newclient.conn
try:
while True:
# data = conn.recv(2048) # receive message from client
data = recv_msg(conn)
uuid = None
ipaddress = None
req = None
if not data :
return False
if data is not None:
data = json.loads(data.decode('utf-8'))
uuid = data['uuid']
req = data['req']
if uuid is not None and req is not None:
newclient.uuid = uuid
cursor, db_connection = setupDBConnection()
if req == "checkvalidsite":
ipaddress = data['ipaddress']
active, info1, info2 = self.checkvalidsite(uuid, ipaddress, cursor, db_connection)
data = {
"req": "checkvalidsite",
"uuid": uuid,
"active": active,
"info1" : info1,
"info2" : info2
}
if not data:
break
# conn.sendall(str.encode(reply))
send_msg(conn, json.dumps(data).encode('utf-8'))
log.info("Server response sent")
#conn.close()
closeDBConnection(cursor, db_connection)
else:
#send no message
a=1
except Exception as e:
log.warning(str(e))
log.warning(traceback.format_exc())
finally:
log.info("UUID Closing connection")
conn.shutdown(socket.SHUT_RDWR)
conn.close()
#conn.close()
def Serverconnect(self):
try: # create socket
self.server_cert = path.join(path.dirname(__file__), "keys/server.crt")
self.server_key = path.join(path.dirname(__file__), "keys/server.key")
self.client_cert = path.join(path.dirname(__file__), "keys/client.crt")
self._context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
self._context.verify_mode = ssl.CERT_REQUIRED
###self._context.load_cert_chain(self.server_cert, self.server_key)
self._context.load_cert_chain(certfile=self.server_cert, keyfile=self.server_key)
###self._context.load_verify_locations(self.client_cert)
self._context.load_verify_locations(cafile=self.client_cert)
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) ###<-- socket.socket() ???
log.info("Socket successfully created")
except socket.error as err:
log.warning("socket creation failed with error %s" %(err))
try: # bind socket to an address
self.sock.bind((self.HOST, self.PORT))
except socket.error as e:
log.warning(str(e))
log.info('Waiting for a Connection..')
self.sock.listen(3)
def Serverwaitforconnection(self):
while True:
Client, addr = self.sock.accept()
conn = self._context.wrap_socket(Client, server_side=True)
log.info('Connected to: ' + addr[0] + ':' + str(addr[1]))
log.info("SSL established. Peer: {}".format(conn.getpeercert()))
newclient = Newclient()
newclient.addr = addr
newclient.conn = conn
thread = Thread(target=self.Serverthreaded_client, args =(newclient, ))
thread.start()
self.threads.append(newclient)
self.ThreadCount += 1
log.info('Thread Number: ' + str(self.ThreadCount))
def startserver():
server = Server()
server.Serverconnect()
server.Serverwaitforconnection()
serverthread = Thread(target=startserver)
serverthread.daemon = False
serverthread.start()
The server accepts the connection with SSL then waits for a message. It investigates the message command, executes the respective function and returns the data from the database as a response (checkvalidsite in this example).
All good so far (as far as I can tell).
I also have the main program that calls the SSLClient and connects.
Main program
remoteclient = SSLclient()
successfulconnection = remoteclient.connect()
siteactive = remoteclient.checkvalidsite()
So far all is well. However I also have the main program reading in frames from multiple cameras. Can be 20 cameras for example. In order to do this I created multiprocessing to deal with the camera load. Each camera or two cameras per, are assigned to a processor (depending on the number of cores in the machine).
(code below has been stripped out to simplify reading)
x = range(3, 6)
for n in x:
processes = multiprocessing.Process(target=activateMainProgram, args=(queue1, queue2, queue3, queue4, remoteclient, ))
processes.start()
When I try pass the remoteclient (SSLClient) as an argument I get the error:
cannot pickle 'SSLContext' object
I then (after reading online) added the code to the SSLClient:
def save_sslcontext(obj):
return obj.__class__, (obj.protocol,)
copyreg.pickle(ssl.SSLContext, save_sslcontext)
but then I get the error:
cannot pickle 'SSLContext' object
There are 2 options I experimented with:
Trying to get the pickle working (which would be ideal) as the processes themselves each need to communicate with the server. So the processes need to call functions from the SSLClient file. But I cannot get over the pickle issue and can't find a solution online
I then placed the remoteclient = SSLClient code outside the main function. Hoping it would run first and then be accessible to the processes. This worked, however what I learnt was that when a process is called (as it does not share memory) it reprocesses the entire file. Meaning if I have 10 processes each with 2 cameras then I would have 10 connections to the server (1 per process). This means on the server side I would also have 10 threads running each connection. Though it works, it seems significantly inefficient.
Being a noob and self taught in Python I am not sure how to resolve the issue and after 3 days, I figured I would reach out for assistance. If I could get assistance with the pickle issue of the SSLClient then I will have one connection that is shared with all processes and 1 thread in the server to deal with them.
P.s. I have cobbled all of the code together myself and being new to Python if you see that I am totally going down the wrong, incorrect, non-professional track, feel free to yell.
Much appreciated.
Update:
If I change the SSLClient code to:
def save_sslcontext(obj):
return obj.__class__, (obj.protocol,)
copyreg.pickle(ssl.SSLContext, save_sslcontext)
Then I get the error:
[WinError 10038] An operation was attempted on something that is not a socket
Not sure what is better..
I have written a script to perform telnet, which i wanted to use for sending commands to my Device Under Test (router).
My Telnet Script:
import sys, time, telnetlib
sys.path.insert(0, '/tmp')
import options
def telnet_connect():
HOST = "%s" %options.DUT_telnet_ip
PORT = "%s" %options.DUT_telnet_port
username = "%s" %options.DUT_telnet_username
password = "%s" %options.DUT_telnet_password
tn = telnetlib.Telnet(HOST, PORT, 10)
time.sleep(5)
tn.write("\n")
tn.read_until("login:", 2)
tn.write(username)
tn.read_until("Password:", 2)
tn.write(password)
tn.write("\n")
response = tn.read_until("$", 5)
return response
def telnet_close():
response = tn.write("exit\n")
return response
I want to use this script in another program which will check the version of the Router by telneting it. I expect a script which will call my above function to perform telnet and send other commands viz. "version" or "ls"
Try to make this more like a class:
import sys, time, telnetlib
sys.path.insert(0, '/tmp')
class TelnetConnection():
def init(self, HOST, PORT):
self.tn = telnetlib.Telnet(HOST, PORT, 10)
def connect(self, username, password):
tn = self.tn
tn.write("\n")
tn.read_until("login:", 2)
tn.write(username)
tn.read_until("Password:", 2)
tn.write(password)
tn.write("\n")
response = tn.read_until("$", 5)
return response
def close(self):
tn = self.tn
response = tn.write("exit\n")
return response
# create here then a method to communicate as you wish
Then you can use it as follows:
import options
HOST = "%s" %options.DUT_telnet_ip
PORT = "%s" %options.DUT_telnet_port
username = "%s" %options.DUT_telnet_username
password = "%s" %options.DUT_telnet_password
connection = TelnetConnection(HOST, PORT)
connection.connect(username, password)
connection.do_all_operations_you_want() # write your own method for that
connection.close()
my script is a server that listens to clients requests and send responses. It handles requests by threading:
class Server:
def __init__(self):
self.host = ''
self.port = 50000
self.backlog = 5
self.size = 1024
self.server = None
self.threads = []
def open_socket(self):
try:
self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server.bind((self.host,self.port))
self.server.listen(5)
except socket.error, (value,message):
if self.server:
self.server.close()
print "Could not open socket: " + message
sys.exit(1)
def run(self):
self.open_socket()
input = [self.server,sys.stdin]
running = 1
while running:
inputready,outputready,exceptready = select.select(input,[],[])
for s in inputready:
if s == self.server:
# handle the server socket
c = Client(self.server.accept())
c.start()
self.threads.append(c)
elif s == sys.stdin:
# handle standard input
junk = sys.stdin.readline()
running = 0
# close all threads
self.server.close()
for c in self.threads:
c.join()
class Client(threading.Thread):
def __init__(self,(client,address)):
threading.Thread.__init__(self)
self.client = client
self.address = address
self.size = 1024
def run(self):
running = 1
while running:
data = self.client.recv(self.size)
if data:
data2 = data.split()
if data2[0] == 'Hello':
status = 'Hello'
#fetch from database users by location
reply= '6'
if data2[0] == 'Index':
status = 'Index'
#fetch from database users by location
reply='I'
db = MySQLdb.connect(host="localhost", # your host, usually localhost
user="root", # your username
passwd="Rambo_9134", # your password
db="secure_login") # name of the data base
# you must create a Cursor object. It will let
# you execute all the queries you need
cur = db.cursor()
# Use all the SQL you like
cur.execute("SELECT ml.member,m.username FROM locations l JOIN memberlocation ml ON(l.id = ml.location) JOIN members m ON(m.id = ml.member) where l.id = 1;")
# print all the first cell of all the rows
data = []
for row in cur.fetchall() :
print row[1]
data.append({row[0]:row[1]})
print 'JSON', json.dumps(data)
reply = data
self.client.send(json.dumps(reply))
else:
self.client.close()
running = 0
if __name__ == "__main__":
s = Server()
s.run()
this script runs perfectly but it stops when i press enter. I have tried many alternatives: deamon, nohup, ... i couldn't make it run as a service in the background. i think this is a programming issue
how can i make this script run in the background as a service ?
For a quick and easy way in a test/dev environment you can use screen.
screen -S mySessionName
This starts a new screen session with the name mySessionName and attaches to that session. Inside this session you can now run your code.
Use Ctrl+A, D to detach from that session. Your code will continue to run.
To reattach to that session use:
screen -r mySessionName
To show all sessions use:
screen -ls
In a production environment however you should be looking at supervisor. This serverfault question might help.
Make a PHP or HTML script devoted solely to running that python program. Then, run that PHP/HTML script on the server and you're good :).
We use multiple sets of predefined passwords here for test servers - I would like to try a portable Python SSH library (like the one below - spur.py) and get it to try each one in succession - but obviously stop when it is successfully connected or if it can't - ask me for a password. I'm after some sort of recursion with the exception handling I think.
def ssh_connection(user, host):
try:
shell = spur.SshShell(
hostname=host,
port=findport(host),
username=user,
password="abc123",
private_key_file= expanduser("~") + "/.ssh/id_rsa",
missing_host_key=spur.ssh.MissingHostKey.accept
)
shell.run(["true"])
return shell
except spur.ssh.ConnectionError as error:
print error
raise
Coming from the Java world I'd check if the object is null and iterate through a list until the end and then ask for a password. I can't see how to do it in Python... Here's an example I found for the list part:
passwords = ['abc123', 'abc456', 'abc789']
for password in passwords: # Second Example
print 'trying password :', password
As Joe mentioned in the comments you can do something similar:
def ssh_connection(user, host, passwords):
err = None
for password in passwords:
try:
shell = spur.SshShell(
hostname=host,
port=findport(host),
username=user,
password=password,
private_key_file= expanduser("~") + "/.ssh/id_rsa",
missing_host_key=spur.ssh.MissingHostKey.accept
)
shell.run(["true"])
return shell
except spur.ssh.ConnectionError as error:
err = error
if err:
raise error
I would cut it in 2 different functions:
def ssh_connection(user, host, password):
"""
try to connect to user:password#host
return None if failed
"""
try:
shell = spur.SshShell(
hostname=host,
port=findport(host),
username=user,
password=password,
private_key_file=expanduser("~") + "/.ssh/id_rsa",
missing_host_key=spur.ssh.MissingHostKey.accept
)
shell.run(["true"])
return shell
except spur.ssh.ConnectionError as error:
print error
return
def try_connection(user, host, passwords):
"""
try all password in passwords to connect to host
if all failed, ask for password via stdin
"""
for password in passwords:
conn = ssh_connection(user, host, password)
if not conn is None:
break
else:
# we never hit the break: ask for passwd
password = ""
while conn is None:
print "please insert password for %s#%s (empty for exit)" % (user,host)
password = raw_input("passwd:") # todo : insert Term seq for hide passwd and then restor
if password == "":
sys.exit(1)
conn = ssh_connection(user, host, password)
return conn
My comment above got mangled, so here is #Joe Doherty suggestion used with code from Ifthikan - thanks!
def loop_ssh_connection(user, host):
shell = None
passw = ['abc123', 'abc456', 'abc789']
while shell is None:
shell = ssh_connection(user, host, passw)
result = shell.run(["ls", "-l"])
print result.output # prints ouput
def ssh_connection(user, host, passw):
err = None
for password in passw:
try:
shell = spur.SshShell(
hostname=host,
port=findport(host),
username=user,
password=password,
private_key_file= expanduser("~") + "/.ssh/id_rsa",
missing_host_key=spur.ssh.MissingHostKey.accept
)
shell.run(["true"])
return shell
except spur.ssh.ConnectionError as error:
err = error
if err:
raise error
I have an IRC bot and I'm trying to get information for game server (GTA SA Multiplayer).
I have ready-to-use query, but I can't implement it into my bot. It works if I try to load the same script, but without getting it into bot's structure. The error it gives me is
NameError: name 'ip' is not defined
I've tried adding the ip address as argument in def(inp,say=None), but it still didn't work. That's the code:
from util import Query
from util import hook
import sys
#hook.command
def serverinfo(inp,ip="",port="",say=None):
ip = "78.129.221.58"
port = 7777
if len(sys.argv) >= 3:
ip = str(sys.argv[1])
port = int(sys.argv[2])
query = Query(ip,port)
info = query.GetInformation()
say(info)
if info['players'] <= 100:
say(query.GetPlayers())
say(query.GetDetailedPlayers())
else: say('can\' get players because players is above 100')
say(query.Ping())
query.Close()
That's Query that I import:
import socket, struct, random, datetime
from cStringIO import StringIO
class Query:
def __init__(self, ip, port):
self.ip, self.port = socket.gethostbyname(ip), port
self.data = StringIO("")
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock.connect((ip, port))
self.sock.settimeout(1)
def CreatePacket(self, opcode):
ips = self.ip.split('.');
packet = "SAMP{0}{1}{2}{3}{4}{5}{6}".format(chr(int(ips[0])), chr(int(ips[1])), chr(int(ips[2])), chr(int(ips[3])), chr(self.port & 0xFF), chr(self.port >> 8 & 0xFF), opcode)
if opcode == 'p':
packet += struct.pack("BBBB", random.randint(0, 255), random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
return packet
def GetInformation(self):
try:
self.sock.send(self.CreatePacket('i'))
info = {}
self.data = StringIO(self.sock.recv(2048))
self.data.read(11)
info['passworded'] = struct.unpack('?', self.data.read(1))[0]
info['players'] = struct.unpack('h', self.data.read(2))[0]
info['maxplayers'] = struct.unpack('h', self.data.read(2))[0]
info['hostname'] = self.data.read(struct.unpack('i', self.data.read(4))[0])
info['gamemode'] = self.data.read(struct.unpack('i', self.data.read(4))[0])
info['mapname'] = self.data.read(struct.unpack('i', self.data.read(4))[0])
except socket.timeout:
info['error'] = 1
return info
def GetRules(self):
try:
self.sock.send(self.CreatePacket('r'))
rules = {}
self.data = StringIO(self.sock.recv(2048))
self.data.read(11)
rulecount = struct.unpack('h', self.data.read(2))[0]
for i in range(rulecount):
name = self.data.read(struct.unpack('b', self.data.read(1))[0])
rules[name] = self.data.read(struct.unpack('b', self.data.read(1))[0])
except socket.timeout:
rules['error'] = 1
return rules
def GetPlayers(self):
try:
self.sock.send(self.CreatePacket('c'))
players = []
self.data = StringIO(self.sock.recv(2048))
self.data.read(11)
playercount = struct.unpack('h', self.data.read(2))[0]
for i in range(playercount):
name = self.data.read(struct.unpack('b', self.data.read(1))[0])
players.append([name, struct.unpack('i', self.data.read(4))[0]])
except socket.timeout:
players = {'error': 1}
return players
def GetDetailedPlayers(self):
try:
self.sock.send(self.CreatePacket('d'))
players = []
self.data = StringIO(self.sock.recv(2048))
self.data.read(11)
playercount = struct.unpack('h', self.data.read(2))[0]
for i in range(playercount):
playerid = struct.unpack('b', self.data.read(1))[0]
name = self.data.read(struct.unpack('b', self.data.read(1))[0])
score = struct.unpack('i', self.data.read(4))[0]
ping = struct.unpack('i', self.data.read(4))[0]
players.append([playerid, name, score, ping])
except socket.timeout:
players = {'error': 1}
return players
def Close(self):
self.sock.close()
def Ping(self):
packet = self.CreatePacket('p')
a = datetime.datetime.now()
self.sock.send(packet)
self.sock.recv(2048)
b = datetime.datetime.now()
c = b - a
return int((c.days * 24 * 60 * 60 + c.seconds) * 1000 + c.microseconds / 1000.0)
class Rcon:
def __init__(self, ip, port, password):
self.ip, self.port, self.password = socket.gethostbyname(ip), port, password
self.data = StringIO("")
self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
self.sock.connect((ip, port))
self.sock.settimeout(0.5)
def CreatePacket(self, opcode, password, command):
ips = self.ip.split('.');
packet = "SAMP{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}{11}{12}".format(chr(int(ips[0])), chr(int(ips[1])), chr(int(ips[2])), chr(int(ips[3])), chr(self.port & 0xFF), chr(self.port >> 8 & 0xFF), opcode, chr(len(password) & 0xFF), chr(len(password) >> 8 & 0xFF), password, chr(len(command) & 0xFF), chr(len(command) >> 8 & 0xFF), command)
return packet
def Send(self, command):
self.sock.send(self.CreatePacket('x', self.password, command))
output = []
while 1:
try:
self.data = StringIO(self.sock.recv(2048))
self.data.read(11)
strlen = struct.unpack('h', self.data.read(2))[0]
if strlen == 0: break
output += [self.data.read(strlen)]
except: break;
return output
def Close(self):
self.sock.close()
Any ideas?
Edit: After some changes I did, gives me the following error:
query = Query(ip,port)
TypeError: 'module' object is not callable
I've basically changed the location of ip and port, moved it out of the serverinfo command.
from util import Query
from util import hook
ip = "78.129.221.58"
port = 7777
query = Query(ip,port)
info = query.GetInformation()
#hook.command
def serverinfo(inp,ip="",port="",say=None):
say(info)
if info['players'] <= 100:
say(query.GetPlayers())
say(query.GetDetailedPlayers())
else: say('can\' get players because players are above 100')
say(query.Ping())
query.Close()
Try adding this to the start of the python code :
ip = "78.129.221.58"
port = 7777
Try
query = Query.Query(ip, port)
The problematic line is this one:
query = Query(ip,port)
If the initialization using the command line parameters fail or if you pass in insufficient arguments, ip will not be initialized resulting in the said error.
Also, a better way of testing out scripts is something like this:
def main():
if len(sys.argv) >= 3:
ip = str(sys.argv[1])
port = int(sys.argv[2])
query = Query(ip,port)
# start using query
else:
raise Exception("Insufficient args passed in")
if __name__ == '__main__':
main()
Raising an exception/error or printing out something guarantees that you know that insufficient args are passed in. Also, maybe move all that code out in the open to some function?