-
Notifications
You must be signed in to change notification settings - Fork 0
/
client.py
219 lines (167 loc) · 5.65 KB
/
client.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#!/usr/bin/python
""" client-side: listening for user inputs for snake,
send user inputs as UDP packets to server,
receives graphical rendering as UDP packets from server,
renders graphics for user"""
import pygame
import Queue
import random, sys
import socket
import struct
import time
import threading
from pygame.locals import *
import helpers
Client_IP = "10.251.213.145"
Server_IP = "10.251.218.96"
Client_send_server_receive = 4000
Server_send_client_receive = 4001
def client(qi, ServerIP):
sender = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
#timer = helpers.Stopwatch()
rate = 0.11
## we start and customize the pygame gui
pygame.init();
s=pygame.display.set_mode((600, 600));
pygame.display.set_caption('Snake');
# initial snake block positions
xs = [290, 290, 290, 290, 290];
ys = [290, 270, 250, 230, 210];
# initial snake direction, score & position of the apple
dirs = 0
score = 0
# we create our apple and our snake blocks
block_size = (20, 20)
appleimage = pygame.Surface((block_size[0], block_size[1]));
# hacky bullsheeeet below so double check
applepos = (330,270)
appleimage.fill((0, 255, 0));
img = pygame.Surface((block_size[0], block_size[1]));
img.fill((255, 0, 0));
# other stuff
f = pygame.font.SysFont('Arial', 20);
loops = 0
curr_gui_number = 0
# round_trip = 0
dirs_list = [-1,-1,-1]
pre1 = -1
pre2 = -1
sttime = time.time()
while True:
# we detect keystrokes and put them in our queue qo
for e in pygame.event.get():
# start_time = time.time()
if e.type == QUIT:
sys.exit(0)
elif e.type == KEYDOWN:
if e.key == K_UP and dirs != 0:
dirs = 2
elif e.key == K_DOWN and dirs != 2:
dirs = 0
elif e.key == K_LEFT and dirs != 1:
dirs = 3
elif e.key == K_RIGHT and dirs != 3:
dirs = 1
# timer.start()
# below looks ugly, but slightly faster than pythonic list modification
pre1 = dirs_list[0]
pre2 = dirs_list[1]
dirs_list[0] = dirs
dirs_list[1] = pre1
dirs_list[2] = pre2
# send packet multiple times for redundancy, sleeps reduce packet loss
packet = helpers.serializer(loops, dirs_list)
sender.sendto(packet, (ServerIP, Client_send_server_receive))
sender.sendto(packet, (ServerIP, Client_send_server_receive))
sender.sendto(packet, (ServerIP, Client_send_server_receive))
# we wait and listen for incomming gui info in qi
while time.time() - sttime - loops*rate < (rate - 0.1):
if qi.qsize() > 0:
#timer.stop()
#print(timer.time_elapsed)
# need to unserialize packet
seq_number,data = helpers.unserializer(qi.get())
# need to handle configuration sequence orderings here
# should it just be < ??
if (curr_gui_number <= seq_number) :
curr_gui_number = seq_number
guidict = data
with qi.mutex:
qi.queue.clear()
if guidict['GameOver'] == True:
sys.exit()
xs = guidict['xs']
ys = guidict['ys']
applepos = guidict['applepos']
score = guidict['score']
break
##rendering when gui info received
s.fill((255, 255, 255))
s.blit(appleimage, applepos);
for i in range(0, len(xs)):
s.blit(img, (xs[i], ys[i]))
t=f.render("score:" + str(score), True, (0, 0, 0));
s.blit(t, (10, 10));
pygame.display.update()
while time.time() - sttime - loops*rate < (rate - 0.001):
pass
loops += 1
## This Tcp wizardry sends timestamp to a server @ TCP_IP TCP_PORT waits delay seconds
## and then executes stuff, here this is print 5
def ClientConnectionHandler(ServerIP = Server_IP, ServerPort = 5005, delay = 2):
TCP_IP = ServerIP
TCP_PORT = ServerPort
BUFFER_SIZE = 256
packer = struct.Struct('d')
reftime = packer.pack(time.time()*1000)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((TCP_IP, TCP_PORT))
# so here can we send the init position/config also
# package it all up wiht reftime, etc., send as one tcp packet
s.send(reftime)
data = s.recv(BUFFER_SIZE)
s.close()
startref = packer.unpack(reftime)
while (time.time() - delay)*1000 < startref[0]: pass
Qci = Queue.Queue()
ClientReciever = threading.Thread(target = helpers.listener, args = (Client_IP,Server_send_client_receive,Qci))
Client = threading.Thread(target = client, args = (Qci, ServerIP))
ClientReciever.start()
Client.start()
ClientReciever.join()
Client.join()
ClientConnectionHandler()
# some UDP packet sending experiments yay!
"""
My_IP = "10.251.54.255"
Sean_IP = "10.251.54.174"
UDP_IP = "10.251.48.230"
UDP_PORT = 4000
# note that data sent must be a string, though we can potentially use serializing libraries to send complex data objects
# my fave serializable python module is cPickle (pretty fast, straightforward to use) so we can look into that if need be
MESSAGE = "Hey Sean!!!"
#print "UDP target IP:", UDP_IP
#print "UDP target port:", UDP_PORT
#print "message:", MESSAGE
# sender: creating socket that will send over Internet using UDP protocol
sender = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# receiver: must bind to given listening address, will then listen for packets in loop later on
#receiver = socket.socket(socket.AF_INET, # Internet
# socket.SOCK_DGRAM) # UDP
#receiver.bind((My_IP, UDP_PORT))
#sender sends data as UDP packet
sender.sendto(MESSAGE, (Sean_IP, UDP_PORT))
"""
"""
while True:
data, addr = receiver.recvfrom(1024) # buffer size is 1024 bytes
print "received message:", data
#sender.close()
receiver.close()
break
"""
# initialize client socket
# does socket need to have different ports for receiving vs listening???
# listen for user inputs (including no input)
# send user inputs to server socket in UDP packets
# receive UDP packets from server and render graphics for user