Пример #1
0
 def set_storm_enabling(self, storm_flag):
     if storm_flag == 0:
         self.game_model.ENABLE_STORM = False
         garage_util.log_garage('storm disabled for room ' + str(self.room_id), True)
     else:
         self.game_model.ENABLE_STORM = True
         garage_util.log_garage('storm enabled for room ' + str(self.room_id), True)
Пример #2
0
    def on_client_pick_up_weapon(self, evt):
        # pick up weapon event
        garage_util.log_garage('pick up weapon event')
        weapon_id = evt.var['weapon_id']
        weapon_type = evt.var['weapon_type']
        equip_slot = evt.var['equip_slot']

        # TODO: add real check
        pick_success = True
#        if weapon_id not in self.game_model.weapons:
#            print 'wid', weapon_id, 'wtype', weapon_type
#            print 'pick up weapon failed'
#            pick_success = False

        if pick_success:

            # destroy weapon event
            evt_destroy_weapon = EventServerDestroyWeapon()
            evt_destroy_weapon.from_cid = evt.from_cid
            evt_destroy_weapon.var['weapon_id'] = weapon_id
            self.game_event_manager.broadcast_server_event(evt_destroy_weapon)

            # pick up weapon event
            evt_pick_up_weapon = EventServerPickUpWeapon()
            evt_pick_up_weapon.from_cid = evt.from_cid
            evt_pick_up_weapon.var['weapon_id'] = weapon_id
            evt_pick_up_weapon.var['weapon_type'] = weapon_type
            self.game_event_manager.send_server_event(evt.from_cid, evt_pick_up_weapon)
Пример #3
0
    def on_client_hit(self, evt):
        # hit event
        """
            | header | damage | hit_pos | hit_cid |
                10        4       4x3        4
        """
        print 'hit event'
        fire_cid = evt.from_cid
        hit_cid = evt.var['hit_cid']
        init_damage = evt.var['damage']
        damage = float(init_damage) / 10000
        self.client_infos[hit_cid].state.HP -= damage
        garage_util.log_garage('client ' + str(fire_cid) + ' hit ' + str(hit_cid) + ', damage ' + str(damage), True)
        evt_damage = EventServerDamage()
        evt_damage.from_cid = hit_cid
        evt_damage.var['fire_cid'] = fire_cid
        evt_damage.var['damage'] = init_damage
        self.game_event_manager.broadcast_server_event(evt_damage)

        # determine death
        # TODO: centralize death event
        if not self.client_infos[hit_cid].state.is_dead and self.client_infos[hit_cid].state.HP <= 0:
            self.client_infos[hit_cid].state.is_dead = True
            garage_util.log_garage('client ' + str(hit_cid) + ' dead', True)
            evt_death = EventServerPlayerDeath()
            evt_death.from_cid = hit_cid
            evt_death.var['killed_cid'] = hit_cid
            evt_death.var['killer_id'] = fire_cid
            self.game_event_manager.broadcast_server_event(evt_death)
Пример #4
0
 def remove_client(self, cid):
     if cid in self.client_infos:
         self.client_infos.pop(cid, None)
         garage_util.log_garage('client ' + str(cid) + ' leaves room ' + str(self.room_id), True)
         # TESTING
         self.post_remove_client(cid)
     else:
         garage_util.log_garage('client ' + str(cid) + ' not in room ' + str(self.room_id) + '. no client removed from room')
Пример #5
0
 def add_client(self, cid):
     if cid not in self.client_infos:
         new_client_state = self.ClientState()
         new_client_info = self.ClientInfo(new_client_state)
         self.client_infos[cid] = new_client_info
         garage_util.log_garage('client ' + str(cid) + ' entered room ' + str(self.room_id), True)
         self.post_add_client(cid)      # TESTING
     else:
         garage_util.log_garage('client ' + str(cid) + ' already in room ' + str(self.room_id))
Пример #6
0
 def on_client_heal(self, evt):
     from_cid = evt.from_cid
     if from_cid in self.client_infos:
         hp = self.client_infos[from_cid].state.HP
         hp += evt.var['heal_val']
         if hp > 100:
             hp = 100
         self.client_infos[from_cid].state.HP = hp
         garage_util.log_garage('client ' + str(from_cid) + ' healed to ' + str(hp), True)
Пример #7
0
 def logout_client(self, cid):
     self.pre_logout_client(cid)  # before logout actions
     if cid in self.client_connections:
         at_room = self.client_connections[cid].at_room
         if at_room >= 0:
             self.quit_room(cid)
         self.client_connections.pop(cid, None)
         garage_util.log_garage('client ' + str(cid) + ' logged out', True)
     else:
         garage_util.log_garage('client ' + str(cid) +
                                ' not logged in. logout failed')
Пример #8
0
    def on_client_start_game(self, evt):
        # echo start game
        # update client initial info
        cid = evt.from_cid
        if cid not in self.client_infos:
            garage_util.log_garage('game start failed. client ' + str(cid) + ' not in room ' + str(self.room_id))
            return
        self.client_infos[cid].state.grid_x = evt.var['grid_x']
        self.client_infos[cid].state.grid_y = evt.var['grid_y']
        self.client_infos[cid].state.pos[0] = evt.var['pos_x']
        self.client_infos[cid].state.pos[1] = evt.var['pos_y']
        self.client_infos[cid].state.pos[2] = evt.var['pos_z']
        self.client_infos[cid].state.rot[0] = evt.var['rot'][0]
        self.client_infos[cid].state.rot[1] = evt.var['rot'][1]
        self.client_infos[cid].state.rot[2] = evt.var['rot'][2]

        # notify new client of existing clients
        evt_spawn_old = EventServerSpawnPlayer()
        for existing_cid in self.client_infos:
            if existing_cid != cid:
                evt_spawn_old.from_cid = existing_cid
                existing_client_state = self.client_infos[existing_cid].state
                evt_spawn_old.var['car_id'] = existing_client_state.vid
                evt_spawn_old.var['grid_x'] = existing_client_state.grid_x
                evt_spawn_old.var['grid_y'] = existing_client_state.grid_y
                evt_spawn_old.var['pos_x'] = existing_client_state.pos[0]
                evt_spawn_old.var['pos_y'] = existing_client_state.pos[1]
                evt_spawn_old.var['pos_z'] = existing_client_state.pos[2]
                evt_spawn_old.var['rot'] = existing_client_state.rot
                evt_spawn_old.var['has_ship'] = '\x00'  # False
                self.game_event_manager.send_server_event(cid, evt_spawn_old)

        # notify all clients to add new client
        evt_spawn_new = EventServerSpawnPlayer()
        evt_spawn_new.from_cid = cid
        current_state = self.client_infos[cid].state
        evt_spawn_new.var['car_id'] = current_state.vid
        evt_spawn_new.var['grid_x'] = current_state.grid_x
        evt_spawn_new.var['grid_y'] = current_state.grid_y
        evt_spawn_new.var['pos_x'] = current_state.pos[0]
        evt_spawn_new.var['pos_y'] = current_state.pos[1]
        evt_spawn_new.var['pos_z'] = current_state.pos[2]
        evt_spawn_new.var['rot'] = current_state.rot
        evt_spawn_new.var['has_ship'] = '\x01'  # True
        # broadcast event
        self.game_event_manager.broadcast_server_event(evt_spawn_new, [])

        # start game
        evt_start_game = EventServerStartGame()
        evt_start_game.from_cid = -1
        self.game_event_manager.send_server_event(cid, evt_start_game)
        pass
Пример #9
0
 def create_room(self, rid=None):
     res_rid = 0
     if rid and rid >= 0:
         res_rid = rid
     while res_rid in self.room_servers:
         res_rid += 1
     new_room_server = self.room_server_class(self, res_rid)
     self.room_servers[rid] = new_room_server
     garage_util.log_garage('room ' + str(res_rid) + ' created', True)
     # run room server
     room_thread = threading.Thread(target=new_room_server.start_server)
     room_thread.start()
     return new_room_server
Пример #10
0
 def login_client(self, cid, token, remote_ip, remote_port):
     res_code = '\x00'
     if cid not in self.client_connections:
         # TESTING
         login_success = GarageWebApi.check_session(cid, token)
         if login_success:
             new_connection = ClientConnection(remote_ip, remote_port)
             self.client_connections[cid] = new_connection
             res_code = '\x00'  # 00 == login success
             garage_util.log_garage('Player ' + str(cid) + ' login success',
                                    True)
             # self.post_login_client(cid)  # after login action
         else:
             res_code = '\x01'  # 01 == authorization failed
             garage_util.log_garage(
                 'Player ' + str(cid) + ' info not correct. login failed',
                 True)
     else:
         res_code = '\x02'  # 02 == login conflict
         garage_util.log_garage('Player ' + str(cid) + ' already logged in')
     pkg_data = pack(
         '<ciicc',
         '\x12',
         get_current_millisecond_clamped(),
         cid,
         '\x0a',  # \x0a == server login result event
         res_code,
     )
     dlen = self.net_communicator.send_data(pkg_data, remote_ip,
                                            remote_port)
     garage_util.log_garage(str(dlen) + ' sent')
Пример #11
0
 def assign_room(self, cid, pkg, rid=-1):
     room_id = 0  # default room id
     if rid >= 0:  # if room id specified, use it
         room_id = rid
     else:
         # TESTING
         while room_id in self.room_servers and len(
                 self.room_servers[room_id].client_infos) >= 80:
             room_id += 1
     target_room = None
     if room_id not in self.room_servers:  # create room if not exists
         target_room = self.create_room(room_id)
     else:
         target_room = self.room_servers[room_id]
     if not target_room:
         garage_util.log_garage('room error. no room available')
     else:
         if cid not in self.client_connections:
             garage_util.log_garage('client ' + str(cid) + ' not logged in')
         elif self.client_connections[cid].at_room >= 0:
             garage_util.log_garage(
                 'client ' + str(cid) + ' already in room ' +
                 str(self.client_connections[cid].at_room), True)
         else:
             garage_util.log_garage('pass client ' + str(cid) +
                                    ' to room ' + str(room_id))
             target_room.run_command('add_client', cid)
             self.client_connections[cid].at_room = room_id
Пример #12
0
 def quit_room(self, cid):
     if cid in self.client_connections:
         at_room = self.client_connections[cid].at_room
         if at_room >= 0:
             garage_util.log_garage('client ' + str(cid) +
                                    ' requests to quit room ' +
                                    str(at_room))
             self.room_servers[at_room].run_command('remove_client', cid)
             self.client_connections[cid].at_room = -1
         else:
             garage_util.log_garage('client ' + str(cid) +
                                    ' not in any room. quit room failed')
     else:
         garage_util.log_garage('client ' + str(cid) +
                                ' not logged in. quit room failed')
Пример #13
0
    def solve_package(self, pkg):
        data = pkg.data
        addr = (pkg.ip, pkg.port)
        op_code = unpack('<c', data[0])[0]
        target_cid = unpack('<i', data[5:5 + 4])[0]

        if op_code <= '\x0f':  # admin package
            if op_code == '\x01':  # login
                token = self.parse_token(data)
                self.login_client(target_cid, token, addr[0], addr[1])
            elif op_code == '\x02':  # logout
                self.logout_client(target_cid)
        elif op_code <= '\x1f':  # game package
            # TODO: move login handling to admin package
            if op_code == '\x12':  # event
                event_id = unpack('<c', data[9:10])[0]
                if event_id == '\x06':  # ping
                    # TESTING
                    if target_cid in self.client_connections:
                        ping_start = unpack('<i', data[1:5])[0]
                        pkg_data = pack('<ciici', '\x12',
                                        get_current_millisecond_clamped(),
                                        target_cid, '\x08', ping_start)
                        dlen = self.net_communicator.send_data(
                            pkg_data, addr[0], addr[1])
                    else:
                        garage_util.log_garage(
                            'no echo for not logged in client' +
                            str(target_cid))
                    return
                if event_id == '\x07':  # login
                    garage_util.log_garage('login event')
                    token = self.parse_token(data)
                    self.login_client(target_cid, token, addr[0], addr[1])
                    return
                if event_id == '\x0b':  # re-login
                    garage_util.log_garage('re-login event')
                    relogin_res = '\x00'  # 00 == ok
                    if target_cid in self.client_connections:
                        pkg_data = pack('<ciicc', '\x12',
                                        get_current_millisecond_clamped(),
                                        target_cid, '\x0d', relogin_res)
                        dlen = self.net_communicator.send_data(
                            pkg_data, addr[0], addr[1])
                    return
                if event_id == '\x08':  # logout
                    # TODO: logout
                    garage_util.log_garage('logout event')
                    self.logout_client(target_cid)
                    return
                if event_id == '\x00':  # match game request
                    # TODO: move join room to separate package
                    garage_util.log_garage('join room event')
                    desired_rid = unpack('<i', data[14:18])[0]
                    garage_util.log_garage('desired room id' +
                                           str(desired_rid))
                    self.assign_room(target_cid, pkg, desired_rid)

            # pass to room if necessary (game event)
            if target_cid in self.client_connections:
                at_room = self.client_connections[target_cid].at_room
                if at_room >= 0:
                    self.room_servers[at_room].run_command(
                        'handle_package', pkg)

        elif op_code <= '\x2f':  # sys info package
            pass
Пример #14
0
 def parse_token(self, pkg_data):
     token = unpack('<i', pkg_data[14:18])[0]
     garage_util.log_garage('get session ' + str(token))
     return token
Пример #15
0
 def post_remove_client(self, cid):
     if len(self.client_infos) == 0:
         garage_util.log_garage('all clients left room ' + str(self.room_id) + '.', True)
         self.clear_room()   # TESTING
Пример #16
0
    def tick_extra(self):
        """
        coroutine = main game model logic
        """
        GAME_LOGIC_INTERVAL = 1.0 / 60
        while True:
            try:
                if self.game_model.game_state == self.GameModel.GameState.GAME_RUNNING:
                    # update fake clients
                    if time.time() - self.last_ai_update_stamp > 1.0 / self.AI_UPDATE_RATE:
                        self.last_ai_update_stamp = time.time()
                        for ai_ind in range(100):
                            if ai_ind in self.client_infos:
                                self.client_infos[ai_ind].state.grid_x = pack('<i', random.randint(0, 5))[0]
                                self.client_infos[ai_ind].state.grid_y = pack('<i', random.randint(0, 5))[0]
                                self.client_infos[ai_ind].need_update = True
                                pass
                    # storm logic
                    if self.game_model.ENABLE_STORM:
                        # calculate shrinking storm
                        if self.game_model.storm_shrink_start_stamp > 0:
                            shrink_time = time.time() - self.game_model.storm_shrink_start_stamp    # time after shrink start
                            if shrink_time > 0:
                                if shrink_time > self.game_model.storm_shrink_duration:
                                    self.game_model.cur_storm_center[0] = self.game_model.next_storm_center[0]
                                    self.game_model.cur_storm_center[1] = self.game_model.next_storm_center[1]
                                    self.game_model.cur_storm_radius = self.game_model.next_storm_radius
                                    self.game_model.storm_shrink_start_stamp = -1
                                    garage_util.log_garage('shrinking done. current radius ' +
                                                           str(self.game_model.cur_storm_radius) +
                                                           ' current center ' +
                                                           str(self.game_model.cur_storm_center[0]) +
                                                           ', ' + str(self.game_model.cur_storm_center[1]))
                                else:
                                    alpha = shrink_time / self.game_model.storm_shrink_duration
                                    self.game_model.cur_storm_center[0] = (1 - alpha) * self.game_model.prev_storm_center[0] + alpha * self.game_model.next_storm_center[0]
                                    self.game_model.cur_storm_center[1] = (1 - alpha) * self.game_model.prev_storm_center[1] + alpha * self.game_model.next_storm_center[1]
                                    self.game_model.cur_storm_radius = (1 - alpha) * self.game_model.prev_storm_radius + alpha * self.game_model.next_storm_radius
                        # calculate storm damage
                        # TESTING
                        if time.time() - self.game_model.last_storm_damage_stamp > 2:   # tick every 2 secs
                            self.game_model.last_storm_damage_stamp = time.time()
                            # SHOULD BE cur_storm_center
                            # cur_center_xy = self.game_model.grid_xy_to_true(21, 51, 160, 160)
                            cur_center_xy = self.game_model.cur_storm_center
                            # print 'damage calc center:', self.game_model.cur_storm_center, ', damage radius:', self.game_model.cur_storm_radius
                            # print 'current storm center', cur_center_xy
                            for cid in self.client_infos:
                                if self.client_infos[cid].state.HP > 0:
                                    # print 'client', cid, 'HP', self.client_infos[cid].state.HP
                                    client_xy = self.game_model.grid_xy_to_true(
                                        unpack('<h', self.client_infos[cid].state.grid_x + '\x00')[0],
                                        unpack('<h', self.client_infos[cid].state.grid_y + '\x00')[0],
                                        unpack('<h', self.client_infos[cid].state.pos[0] + '\x00')[0],
                                        unpack('<h', self.client_infos[cid].state.pos[1] + '\x00')[0]
                                    )
                                    # print 'client pos', client_xy
                                    dx = client_xy[0] - cur_center_xy[0]
                                    dy = client_xy[1] - cur_center_xy[1]
                                    if dx * dx + dy * dy > self.game_model.cur_storm_radius * self.game_model.cur_storm_radius:
                                        damage = 10000
                                        # print 'storm damage', damage
                                        self.client_infos[cid].state.HP -= damage / 10000
                                        evt_damage = EventServerDamage()
                                        evt_damage.from_cid = cid   # damaged client
                                        evt_damage.var['fire_cid'] = -1  # server
                                        evt_damage.var['damage'] = damage
                                        self.game_event_manager.broadcast_server_event(evt_damage)

                                        # determine death
                                        # TODO: centralize death event
                                        if not self.client_infos[cid].state.is_dead and self.client_infos[cid].state.HP <= 0:
                                            self.client_infos[cid].state.is_dead = True
                                            garage_util.log_garage('client ' + str(cid) + ' dead', True)
                                            evt_death = EventServerPlayerDeath()
                                            evt_death.from_cid = cid
                                            evt_death.var['killed_cid'] = cid
                                            evt_death.var['killer_id'] = -1  # -1 == storm
                                            self.game_event_manager.broadcast_server_event(evt_death)
                        # update sand storm
                        storm_span = self.game_model.cur_storm_duration
                        if self.game_model.storm_pkg_count > 1:   # if not first update, accumulate shrink delay and shrink time
                            storm_span = self.game_model.cur_storm_duration + self.game_model.storm_shrink_delay + self.game_model.storm_shrink_duration
                        if time.time() - self.game_model.last_storm_update_stamp > storm_span:
                            # if time.time() - self.start_stamp < 15:  # TESTING
                            #     return
                            # counter update
                            self.game_model.storm_pkg_count += 1
                            print 'storm update at time', time.time()
                            self.game_model.last_storm_update_stamp = time.time()
                            # calculate next storm
                            # self.game_model.cur_storm_radius = self.game_model.next_storm_radius
                            if self.game_model.storm_pkg_count > 1:
                                self.game_model.next_storm_radius -= 5000
                                while self.game_model.next_storm_radius <= 0:
                                    self.game_model.next_storm_radius += 5000
                                self.game_model.next_storm_center[0] = self.game_model.cur_storm_center[0] + random.randint(1, 20000) - 10000
                                self.game_model.next_storm_center[1] = self.game_model.cur_storm_center[1] + random.randint(1, 20000) - 10000
                            # self.game_model.cur_storm_duration = 15
                            # must update last storm info
                            for i in range(len(self.game_model.cur_storm_center)):
                                self.game_model.prev_storm_center[i] = self.game_model.cur_storm_center[i]
                            self.game_model.prev_storm_radius = self.game_model.cur_storm_radius
                            # send update event
                            evt_storm_update = EventServerUpdateSandStorm()
                            evt_storm_update.from_cid = -1
                            # TESTING
                            next_grids = self.game_model.true_xy_to_grid(self.game_model.next_storm_center[0], self.game_model.next_storm_center[1])
                            evt_storm_update.var['cur_center'] = [
                                pack('<h', next_grids[0])[0],
                                pack('<h', next_grids[1])[0],
                                pack('<h', next_grids[2])[0],
                                pack('<h', next_grids[3])[0],
                            ]  # ['\x15', '\x33', '\xa0', '\xa0']  # self.game_model.cur_storm_center
                            evt_storm_update.var['cur_radius'] = self.game_model.next_storm_radius  # ACTUALLY NEXT STORM INFO
                            shrink_speed = float(
                                self.game_model.cur_storm_radius - self.game_model.next_storm_radius) / self.game_model.storm_shrink_duration
                            if self.game_model.storm_pkg_count == 1:
                                shrink_speed = 10000
                            evt_storm_update.var['shrink_speed'] = int(shrink_speed)
                            evt_storm_update.var['time_to_appear_next'] = self.game_model.cur_storm_duration
                            evt_storm_update.var['time_to_shrink'] = self.game_model.storm_shrink_delay
                            self.game_event_manager.broadcast_server_event(evt_storm_update)
                            # print 'center sent:', self.game_model.next_storm_center

                            # set shrink start stamp, otherwise the shrink won't start
                            if self.game_model.storm_pkg_count > 1:  # IF NOT FIRST PACKAGE
                                self.game_model.storm_shrink_start_stamp = time.time() + self.game_model.storm_shrink_delay

                            # print 'storm radius:', self.game_model.cur_storm_radius
                            # print 'time until next storm:', self.game_model.cur_storm_duration
                            # print 'shrink duration:', self.game_model.storm_shrink_duration
                    pass
            except Exception, e:
                print e
            gevent.sleep(GAME_LOGIC_INTERVAL)
Пример #17
0
 def clear_room(self):
     garage_util.log_garage('clear room ' + str(self.room_id), True)
     self.game_model.game_model_init()