chichilku3 5.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. checksums.yaml +7 -0
  2. data/bin/chichilku3 +3 -0
  3. data/bin/chichilku3-server +3 -0
  4. data/client.json +6 -0
  5. data/lib/client/chichilku3.rb +18 -0
  6. data/lib/client/client.rb +289 -0
  7. data/lib/client/client_cfg.rb +15 -0
  8. data/lib/client/gui.rb +492 -0
  9. data/lib/client/img/background1024x512.png +0 -0
  10. data/lib/client/img/battle1024x576.png +0 -0
  11. data/lib/client/img/connecting1024x512.png +0 -0
  12. data/lib/client/img/grass1024x512.png +0 -0
  13. data/lib/client/img/grey128.png +0 -0
  14. data/lib/client/img/menu1920x1080.png +0 -0
  15. data/lib/client/img/stick128/stick0.png +0 -0
  16. data/lib/client/img/stick128/stick1.png +0 -0
  17. data/lib/client/img/stick128/stick2.png +0 -0
  18. data/lib/client/img/stick128/stick3.png +0 -0
  19. data/lib/client/img/stick128/stick4.png +0 -0
  20. data/lib/client/img/stick128/stick5.png +0 -0
  21. data/lib/client/img/stick128/stick_crouching0.png +0 -0
  22. data/lib/client/img/stick128/stick_crouching1.png +0 -0
  23. data/lib/client/img/stick128/stick_crouching2.png +0 -0
  24. data/lib/client/img/stick128/stick_crouching3.png +0 -0
  25. data/lib/client/img/stick128/stick_crouching4.png +0 -0
  26. data/lib/client/img/stick128/stick_crouching5.png +0 -0
  27. data/lib/client/scoreboard.rb +25 -0
  28. data/lib/client/test.rb +39 -0
  29. data/lib/client/text.rb +86 -0
  30. data/lib/server/chichilku3_server.rb +293 -0
  31. data/lib/server/gamelogic.rb +121 -0
  32. data/lib/server/server_cfg.rb +6 -0
  33. data/lib/share/config.rb +53 -0
  34. data/lib/share/console.rb +18 -0
  35. data/lib/share/network.rb +145 -0
  36. data/lib/share/player.rb +286 -0
  37. data/server.json +4 -0
  38. metadata +81 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: e90a2851bf8d4a37c61c581919708cd7fc75c8592291755c0281e090e03e5d84
4
+ data.tar.gz: 10e3825729ef2c5a0f17543a8c4519cbbf61f021805d624b54a8f79e314db898
5
+ SHA512:
6
+ metadata.gz: 2452e5c7f2764142ea99f151828994b6c163d301370835558a464c8215c6f1689036a2de9ed681b7d937d90787a8f1d124c241848e63a7d79e3f0fc3c40937be
7
+ data.tar.gz: 610086071507b30d4acdaaefdb029f485d1c2696c3df1a36369e224f14a9afe67dbc7454affbb3c0d968d47bbd3eeef323223e7f9530924cea85c0e14ecc6399
data/bin/chichilku3 ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'client/chichilku3'
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'server/chichilku3_server'
data/client.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "ip": "localhost",
3
+ "port": 9900,
4
+ "username": "00000000",
5
+ "fullscreen": false
6
+ }
@@ -0,0 +1,18 @@
1
+ require 'gosu'
2
+ require_relative 'client'
3
+ require_relative '../share/console'
4
+ require_relative '../share/player'
5
+ require_relative 'gui'
6
+ require_relative 'client_cfg'
7
+
8
+ # The project root is the game
9
+ class Game
10
+ def initialize
11
+ console = Console.new
12
+ cfg = ClientCfg.new(console, "client.json")
13
+ gui = Gui.new(cfg)
14
+ gui.show
15
+ end
16
+ end
17
+
18
+ Game.new
@@ -0,0 +1,289 @@
1
+ require 'socket'
2
+ require_relative '../share/network'
3
+ require_relative '../share/player'
4
+
5
+ STATE_ERROR = -2
6
+ STATE_MENU = -1
7
+ STATE_OFFLINE = 0
8
+ STATE_CONNECTING = 1
9
+ STATE_INGAME = 2
10
+
11
+ # Networking part of the game clientside
12
+ class Client
13
+ attr_reader :id, :state
14
+ def initialize(console, cfg)
15
+ @id = nil
16
+ @tick = 0
17
+ @state = STATE_MENU
18
+ @cfg = cfg
19
+
20
+ @console = console
21
+ @console.log "LOAD #{@s}"
22
+
23
+ @s = nil # network socket (set in connect() method)
24
+
25
+ # state variables
26
+ @req_playerlist = Time.now - 8
27
+
28
+ # return values
29
+ @players = []
30
+ @flags = { skip: false, state: @state, gamestate: 'g',id: nil }
31
+ end
32
+
33
+ def reset()
34
+ @id = nil
35
+ @tick = 0
36
+ @state = STATE_MENU
37
+ @players = []
38
+ @flags = { skip: false, state: @state, gamestate: 'g',id: nil }
39
+ end
40
+
41
+ def connect(ip, port)
42
+ reset
43
+ @s = TCPSocket.open(ip, port)
44
+ @s.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) # nagle's algorithm-
45
+ @state = STATE_CONNECTING
46
+ end
47
+
48
+ def disconnect()
49
+ return if @state == STATE_MENU
50
+ @console.log "disconnecting from server."
51
+ @s.close
52
+ @s = nil
53
+ reset
54
+ end
55
+
56
+ def tick(client_data, protocol, tick)
57
+ return nil if @state == STATE_MENU
58
+
59
+ # sleep(1)
60
+ @tick = tick
61
+ @flags[:skip] = false
62
+
63
+ # send data to the server
64
+ send_data(client_data, protocol)
65
+
66
+ # get data from the server + implicit return
67
+ data = fetch_server_data
68
+ return nil if data.nil?
69
+
70
+ # only process the long packages and ignore ip packages here
71
+ return nil if data.length != SERVER_PACKAGE_LEN
72
+
73
+ # save protocol and cut it off
74
+ msg = handle_protocol(data[0].to_i, data[1], data[2..-1])
75
+ [@players, @flags, msg]
76
+ end
77
+
78
+ private
79
+
80
+ def update_state(state)
81
+ @flags[:state] = state
82
+ @state = state
83
+ end
84
+
85
+ def handle_protocol(protocol, p_status, data)
86
+ @console.dbg "HANDLE PROTOCOL=#{protocol} status=#{p_status}"
87
+ if protocol == 0 # error packet
88
+ code = data[0..2]
89
+ error_msg = data[3..-1]
90
+ if code == NET_ERR_FULL
91
+ @console.log "server is full."
92
+ elsif code == NET_ERR_DISCONNECT
93
+ @console.log "disconnected by server."
94
+ elsif code == NET_ERR_KICK
95
+ @console.log "kicked by server."
96
+ elsif code == NET_ERR_BAN
97
+ @console.log "banned by server."
98
+ elsif code == NET_ERR_SERVER_OUTDATED
99
+ @console.log "failed to connect to server: server is outdated."
100
+ @console.log error_msg
101
+ elsif code == NET_ERR_CLIENT_OUTDATED
102
+ @console.log "failed to connect to server: your client is outdated."
103
+ else
104
+ @console.log "ERROR unkown error code code=#{code} data=#{data}"
105
+ return
106
+ end
107
+ @state = STATE_ERROR
108
+ return [0, code, error_msg]
109
+ elsif protocol == 1 # update package
110
+ server_package_to_player_array(data)
111
+ elsif protocol == 2 # id packet
112
+ if @id.nil?
113
+ id_packet(data)
114
+ else
115
+ @console.log "WARNING got unexpected id packet=#{data}"
116
+ end
117
+ elsif protocol == 3 # name packet
118
+ protocol_names(data)
119
+ elsif protocol == 4 # command respond
120
+ @console.log "server respond: #{data}"
121
+ return [1, data]
122
+ else
123
+ @console.log "ERROR unkown protocol=#{protocol} data=#{data}"
124
+ end
125
+ nil
126
+ end
127
+
128
+ def send_data(data, protocol)
129
+ if @id.nil?
130
+ # request id has priority
131
+ # resend after 100 ticks if no respond
132
+ name = @cfg.data['username'].ljust(5, '-')
133
+ net_write("1l#{name}") if (@tick % 200).zero?
134
+ return
135
+ end
136
+
137
+ # if no playerlist yet -> request one
138
+ if @players == [] && @req_playerlist < Time.now - 4
139
+ net_write("3l#{id}#{GAME_VERSION}")
140
+ @console.log('requesting a playerlist')
141
+ @req_playerlist = Time.now
142
+ return
143
+ end
144
+
145
+ # prefix data with id
146
+ # prot 2 = update pck
147
+ # prot updated to dynamic becuase we now also send cmds
148
+ # data = format("#{protocol}l%02d#{data.join('')}", @id) # old 2byte id
149
+ data = "#{protocol}l#{@id}#{data.join('')}" # new 1byte id
150
+ net_write(data)
151
+ end
152
+
153
+ def set_id(id)
154
+ if id > MAX_CLIENTS || id < 1
155
+ @console.log "Errornous id=#{id}"
156
+ return false
157
+ end
158
+ @id = id
159
+ @console.log "Set ID=#{@id}"
160
+ @flags[:id] = @id
161
+ true
162
+ end
163
+
164
+ def grab_id(data)
165
+ @console.log 'Trying to read id...'
166
+ @playercount = data[0..1]
167
+ id = data[2..3].to_i
168
+ set_id(id)
169
+ update_state(STATE_INGAME)
170
+ end
171
+
172
+ def id_packet(data)
173
+ # protocol 2
174
+ # the id protocol contains fresh client id
175
+ # and server version
176
+ grab_id(data)
177
+ get_server_version(data)
178
+ end
179
+
180
+ def get_server_version(data)
181
+ server_version = data[4..8]
182
+ @console.log "server version='#{server_version}'"
183
+ end
184
+
185
+ def fetch_server_data
186
+ server_data = save_read(@s, SERVER_PACKAGE_LEN)
187
+ return nil if server_data == ''
188
+
189
+ @console.dbg "recived data: #{server_data}"
190
+ server_data
191
+ end
192
+
193
+ def net_write(data)
194
+ if data.length != CLIENT_PACKAGE_LEN
195
+ @console.log "ERROR wrong pack len: #{data.length}/#{CLIENT_PACKAGE_LEN} pck: #{data}"
196
+ exit
197
+ end
198
+ @s.write(data)
199
+ @console.dbg "sent: #{data}"
200
+ end
201
+
202
+ # TODO: add protocol class for this
203
+ # TODO: protocol_names should create the player objects
204
+ # AND: server_package_to_player_array should update the objs
205
+
206
+ # playername package
207
+ # And its dependencies:
208
+ def protocol_names(data)
209
+ # 3 0 00 00000 00 00000 00 00000 000
210
+ playercount = data[0].to_i
211
+ @flags[:gamestate] = data[1]
212
+ data = data[2..-1]
213
+ p_strs = protocol_names_to_player_strs(playercount, data)
214
+ protocol_names_strs_to_objs(p_strs)
215
+ end
216
+
217
+ def protocol_names_to_player_strs(slots, data)
218
+ players = []
219
+ slots.times do |index|
220
+ players[index] = data[index * 7..index * 7 + 6]
221
+ end
222
+ players
223
+ end
224
+
225
+ def protocol_names_strs_to_objs(player_strs)
226
+ players = []
227
+ player_strs.each do |player_str|
228
+ id = player_str[0].to_i
229
+ score = net_unpack_int(player_str[1])
230
+ name = player_str[2..-1]
231
+ players << Player.new(id, 0, 0, score, name) unless id.zero?
232
+ end
233
+ # debug
234
+ players.each { |p| @console.dbg "player=#{p.id} score=#{p.score} name='#{p.name}'" }
235
+ @flags[:skip] = true # dont redner players at position zer0
236
+ @players = players
237
+ end
238
+
239
+ # server_package_to_player_array
240
+ # And its dependencies:
241
+ def server_package_to_player_array(data)
242
+ # /(?<count>\d{2})(?<player>(?<id>\d{2})(?<x>\d{3})(?<y>\d{3}))/
243
+ # @console.log "data: #{data}"
244
+ slots = data[0].to_i # save occupado slots
245
+ # gamestate = data[1].to_i # save gamestate
246
+ @flags[:gamestate] = data[1]
247
+ # @console.log "gamestate: " + @flags[:gamestate]
248
+ data = data[2..-1] # cut slots and gamestate off
249
+ players = server_package_to_player_strs(slots, data)
250
+ # @console.log "players: \n#{players}"
251
+ player_strs_to_objects(players)
252
+ end
253
+
254
+ def server_package_to_player_strs(slots, data)
255
+ players = []
256
+ slots.times do |index|
257
+ players[index] = data[index * 8..index * 8 + 7]
258
+ end
259
+ players
260
+ end
261
+
262
+ def player_strs_to_objects(player_strs)
263
+ players = []
264
+ player_strs.each do |player_str|
265
+ id = player_str[0].to_i
266
+ score = net_unpack_int(player_str[1])
267
+ unused = player_str[2]
268
+ net_state = player_str[3]
269
+ x = net_unpack_bigint(player_str[4..5])
270
+ y = net_unpack_bigint(player_str[6..7])
271
+ # puts "id: #{id} x: #{x} y: #{y}"
272
+ # players << Player.new(id, x, y) unless id.zero?
273
+
274
+ @console.dbg "-- updt player id=#{id} score=#{score}--"
275
+ p_index = Player.get_player_index_by_id(@players, id)
276
+ @console.dbg "@players index=#{p_index}"
277
+ @console.dbg "players: \n #{@players}"
278
+ next if p_index.nil?
279
+
280
+ @console.dbg "got player: #{@players[p_index]}"
281
+ new_player = Player.update_player(@players, id, x, y, score)
282
+ new_player.net_to_state(net_state)
283
+ @players[Player.get_player_index_by_id(@players, id)] = new_player
284
+ end
285
+ # debug
286
+ players.each { |p| @console.dbg "player=#{p.id} pos=#{p.x}/#{p.y}" }
287
+ players
288
+ end
289
+ end
@@ -0,0 +1,15 @@
1
+ require 'json'
2
+ require_relative '../share/network'
3
+ require_relative '../share/config'
4
+
5
+ # The client side repository usign JSON
6
+ class ClientCfg < Config
7
+ def sanitize_data(data)
8
+ data = JSON.parse(File.read(@file))
9
+ if data['username'].length > NAME_LEN
10
+ data['username'] = data['username'][0..NAME_LEN - 1]
11
+ @console.log "username to long chopped to '#{data['username']}'"
12
+ end
13
+ data
14
+ end
15
+ end