v2016.09.01

This commit is contained in:
lcdr
2016-09-01 10:08:16 +02:00
parent 1bad8b75c0
commit 2ec878e712
26 changed files with 217 additions and 109 deletions

View File

@@ -17,17 +17,8 @@ or
If you don't want to compile the packages yourself, you can download precompiled ones from http://www.lfd.uci.edu/~gohlke/pythonlibs/ .
##### Bugfixes
ZEO has some unfixed bugs which you'll need to fix manually:
in `<Python installation directory>/Lib/site-packages/ZEO/zrpc/client.py`
line 453
comment out:
if socktype != socket.SOCK_STREAM:
continue
and in `<Python installation directory>/Lib/site-packages/ZEO/zrpc/trigger.py`
ZEO has an unfixed bug which you'll need to fix manually:
in `<Python installation directory>/Lib/site-packages/ZEO/zrpc/trigger.py`
line 235
change

View File

@@ -16,6 +16,11 @@ from .mission import MissionProgress, MissionState, TaskType
log = logging.getLogger(__name__)
class TerminateType:
Range = 0
User = 1
FromInteraction = 2
class BuildType:
BuildNowhere = 0
BuildInWorld = 1
@@ -230,6 +235,12 @@ class CharacterComponent:
del self._v_server.dropped_loot[self.object_id]
self.vehicle_id = 0
self.online = False
self.check_for_leaks()
def check_for_leaks(self):
if self.temp_models:
print("Temp Models not empty")
print(self.temp_models)
async def transfer_to_world(self, world, respawn_point_name=None):
if respawn_point_name is not None:
@@ -261,7 +272,7 @@ class CharacterComponent:
if task.type == TaskType.ObtainItem:
for item in self.items:
if item is not None and item.lot in task.target:
mission_progress.increment_task(task, self._v_server, self, increment=item.amount)
mission_progress.increment_task(task, self, increment=item.amount)
if task.value == task.target_value:
break
@@ -312,6 +323,9 @@ class CharacterComponent:
def notify_mission_task(self, address, mission_id:c_int=None, task_mask:c_int=None, updates:(c_ubyte, c_float)=None):
pass
def terminate_interaction(self, address, obj_id_terminator:c_int64=None, type:c_int=None):
pass
def request_use(self, address, is_multi_interact_use:c_bit=None, multi_interact_id:c_uint=None, multi_interact_type:c_int=None, object_id:c_int64=None, secondary:c_bit=False):
if not is_multi_interact_use:
assert multi_interact_id == 0
@@ -334,7 +348,7 @@ class CharacterComponent:
if mission.state == MissionState.Active:
for task in mission.tasks:
if task.type == TaskType.Interact and task.target == obj.lot:
mission.increment_task(task, self._v_server, self)
mission.increment_task(task, self)
def get_flag(self, flag_id):
return bool(self.flags & (1 << flag_id))
@@ -350,7 +364,7 @@ class CharacterComponent:
if mission.state == MissionState.Active:
for task in mission.tasks:
if task.type == TaskType.Flag and flag_id in task.target:
mission.increment_task(task, self._v_server, self)
mission.increment_task(task, self)
def player_loaded(self, address, player_id:c_int64=None):
@@ -454,7 +468,7 @@ class CharacterComponent:
self._v_server.mail.send_mail(self.name, "Bug Report: "+selection, body, account.characters.selected())
def request_smash_player(self, address):
self._v_server.send_game_message(self.request_die, unknown_bool=False, death_type="", direction_relative_angle_xz=0, direction_relative_angle_y=0, direction_relative_force=0, killer_id=self.object_id, loot_owner_id=0, address=self.address)
self.request_die(None, unknown_bool=False, death_type="", direction_relative_angle_xz=0, direction_relative_angle_y=0, direction_relative_force=0, killer_id=self.object_id, loot_owner_id=0)
def handle_u_g_c_equip_post_delete_based_on_edit_mode(self, address, inv_item:c_int64=None, items_total:c_int=0):
pass

View File

@@ -15,4 +15,4 @@ class CollectibleComponent:
if mission.state == MissionState.Active:
for task in mission.tasks:
if task.type == TaskType.Collect and task.target == self.lot:
mission.increment_task(task, self._v_server, player)
mission.increment_task(task, player)

View File

@@ -1,7 +1,6 @@
import random
from ..bitstream import c_bit, c_float, c_int, c_int64, c_uint
from ..math.vector import Vector3
from .comp108 import Comp108Component
from .mission import MissionState, TaskType
from .stats import StatsSubcomponent
@@ -20,6 +19,7 @@ class DestructibleComponent:
self.life = self.max_life
self.armor = self.max_armor
self.imagination = self.max_imagination
self.is_smashable = comp[7]
def serialize(self, out, is_creation):
if is_creation:
@@ -44,12 +44,6 @@ class DestructibleComponent:
loot.append(lot)
return loot
def drop_loot(self, lot, owner):
object_id = self._v_server.new_spawned_id()
self._v_server.dropped_loot.setdefault(owner.object_id, {})[object_id] = lot
self._v_server.send_game_message(owner.drop_client_loot, use_position=True, spawn_position=self.position, final_position=Vector3(self.position.x+(random.random()-0.5)*20, self.position.y, self.position.z+(random.random()-0.5)*20), currency=0, item_template=lot, loot_id=object_id, owner=owner.object_id, source_obj=self.object_id, address=owner.address)
def request_die(self, address, unknown_bool:c_bit=None, death_type:"wstr"=None, direction_relative_angle_xz:c_float=None, direction_relative_angle_y:c_float=None, direction_relative_force:c_float=None, kill_type:c_int=0, killer_id:c_int64=None, loot_owner_id:c_int64=None):
if self.armor != 0:
self.armor = 0
@@ -67,7 +61,7 @@ class DestructibleComponent:
if mission.state == MissionState.Active:
for task in mission.tasks:
if task.type == TaskType.KillEnemy and self.lot in task.target:
mission.increment_task(task, self._v_server, killer)
mission.increment_task(task, killer)
# drops

View File

@@ -183,7 +183,7 @@ class InventoryComponent:
if mission.state == MissionState.Active:
for task in mission.tasks:
if task.type == TaskType.ObtainItem and stack.lot in task.target:
mission.increment_task(task, self._v_server, self)
mission.increment_task(task, self)
return stack
@@ -282,10 +282,14 @@ class InventoryComponent:
return
def move_item_between_inventory_types(self, address, inventory_type_a:c_int=None, inventory_type_b:c_int=None, object_id:c_int64=None, show_flying_loot:c_bit=True, stack_count:c_uint=1, template_id:c_int=-1):
assert stack_count == 1
source = self.inventory_type_to_inventory(inventory_type_a)
for item in source:
if item is not None and (item.object_id == object_id or item.lot == template_id):
self.add_item_to_inventory(item.lot, item.amount, inventory_type=inventory_type_b, show_flying_loot=show_flying_loot)
self.remove_item_from_inv(inventory_type_a, item)
break
if stack_count == 0:
move_stack_count = item.amount
else:
assert item.amount >= stack_count
move_stack_count = stack_count
new_item = self.add_item_to_inventory(item.lot, move_stack_count, inventory_type=inventory_type_b, show_flying_loot=show_flying_loot)
self.remove_item_from_inv(inventory_type_a, item, amount=move_stack_count)
return new_item

View File

@@ -38,6 +38,23 @@ class MissionState:
ReadyToComplete = 4
Completed = 8
def check_prereqs(mission_id, player):
player_missions = {mission.id: mission.state for mission in player.missions}
prereqs = player._v_server.db.missions[mission_id][1]
for prereq_ors in prereqs:
for prereq_mission in prereq_ors:
if isinstance(prereq_mission, tuple): # prereq requires special mission state
prereq_mission, prereq_mission_state = prereq_mission
else:
prereq_mission_state = MissionState.Completed
if prereq_mission in player_missions and player_missions[prereq_mission] == prereq_mission_state:
break # an element was found, this prereq_ors is satisfied
else:
break # no elements found, not satisfied, checking further prereq_ors unnecessary
else: # all preconditions satisfied
return True
return False
class MissionTask(Persistent):
def __init__(self, task_type, target, target_value, parameter):
self.type = task_type
@@ -64,20 +81,23 @@ class MissionProgress(Persistent):
self.tasks = [MissionTask(task_type, target, target_value, parameter) for task_type, target, target_value, parameter in mission_data[2]]
self.is_mission = mission_data[3]
def increment_task(self, task, server, player, increment=1):
def increment_task(self, task, player, increment=1):
if task.value == task.target_value:
return
if not self.is_mission and not check_prereqs(self.id, player):
return
task.value = min(task.value+increment, task.target_value)
task_index = self.tasks.index(task)
server.send_game_message(player.notify_mission_task, self.id, task_mask=1<<(task_index+1), updates=[task.value], address=player.address)
player._v_server.send_game_message(player.notify_mission_task, self.id, task_mask=1<<(task_index+1), updates=[task.value], address=player.address)
if not self.is_mission:
for task in self.tasks:
if task.value < task.target_value:
break
else:
self.complete(server, player)
self.complete(player)
def complete(self, server, player):
def complete(self, player):
self.state = MissionState.Completed
if self.is_mission:
@@ -85,23 +105,23 @@ class MissionProgress(Persistent):
else:
source_type = LootType.Achievement
server.send_game_message(player.notify_mission, self.id, mission_state=MissionState.Unavailable, sending_rewards=True, address=player.address)
server.send_game_message(player.set_currency, currency=player.currency + self.rew_currency, position=Vector3.zero, source_type=source_type, address=player.address)
server.send_game_message(player.modify_lego_score, self.rew_universe_score, source_type=source_type, address=player.address)
player._v_server.send_game_message(player.notify_mission, self.id, mission_state=MissionState.Unavailable, sending_rewards=True, address=player.address)
player._v_server.send_game_message(player.set_currency, currency=player.currency + self.rew_currency, position=Vector3.zero, source_type=source_type, address=player.address)
player._v_server.send_game_message(player.modify_lego_score, self.rew_universe_score, source_type=source_type, address=player.address)
for lot, amount in self.rew_items:
player.add_item_to_inventory(lot, amount, source_type=source_type)
if self.rew_emote is not None:
server.send_game_message(player.set_emote_lock_state, lock=False, emote_id=self.rew_emote, address=player.address)
player._v_server.send_game_message(player.set_emote_lock_state, lock=False, emote_id=self.rew_emote, address=player.address)
player.max_life += self.rew_max_life
player.max_imagination += self.rew_max_imagination
if self.rew_max_items:
server.send_game_message(player.set_inventory_size, inventory_type=InventoryType.Items, size=len(player.items)+self.rew_max_items, address=player.address)
player._v_server.send_game_message(player.set_inventory_size, inventory_type=InventoryType.Items, size=len(player.items)+self.rew_max_items, address=player.address)
server.send_game_message(player.notify_mission, self.id, mission_state=MissionState.Completed, sending_rewards=False, address=player.address)
player._v_server.send_game_message(player.notify_mission, self.id, mission_state=MissionState.Completed, sending_rewards=False, address=player.address)
# No longer required, delete to free memory in db
@@ -121,9 +141,9 @@ class MissionProgress(Persistent):
if mission.state == MissionState.Active:
for task in mission.tasks:
if task.type == TaskType.MissionComplete and self.id in task.target:
mission.increment_task(task, server, player)
mission.increment_task(task, player)
server.commit()
player._v_server.commit()
class MissionNPCComponent:
def __init__(self, comp_id):
@@ -147,18 +167,7 @@ class MissionNPCComponent:
break
elif offers_mission:
log.debug("assessing %i", mission_id)
prereqs = self._v_server.db.missions[mission_id][1]
for prereq_ors in prereqs:
for prereq_mission in prereq_ors:
if isinstance(prereq_mission, tuple): # prereq requires special mission state
prereq_mission, prereq_mission_state = prereq_mission
else:
prereq_mission_state = MissionState.Completed
if prereq_mission in player_missions and player_missions[prereq_mission] == prereq_mission_state:
break # an element was found, this prereq_ors is satisfied
else:
break # no elements found, not satisfied, checking further prereq_ors unnecessary
else: # all preconditions satisfied
if check_prereqs(mission_id, player):
offer = mission_id
if offer is not None:
@@ -185,7 +194,7 @@ class MissionNPCComponent:
assert is_complete
for mission_progress in player.missions:
if mission_progress.id == mission_id:
mission_progress.complete(self._v_server, player)
mission_progress.complete(player)
break
def request_linked_mission(self, address, player_id:c_int64=None, mission_id:c_int=None, mission_offered:c_bit=None):

View File

@@ -19,6 +19,16 @@ class ModularBuildComponent:
player = self._v_server.accounts[address].characters.selected()
self._v_server.send_game_message(player.start_arranging_with_item, first_time, self.object_id, player.position, source_bag, source_id, source_lot, source_type, target_id, target_lot, target_pos, target_type, address=address)
def done_arranging_with_item(self, address, new_source_bag:c_int=None, new_source_id:c_int64=None, new_source_lot:c_int=None, new_source_type:c_int=None, new_target_id:c_int64=None, new_target_lot:c_int=None, new_target_type:c_int=None, new_target_pos:Vector3=None, old_item_bag:c_int=None, old_item_id:c_int64=None, old_item_lot:c_int=None, old_item_type:c_int=None):
player = self._v_server.accounts[address].characters.selected()
for model in player.temp_models.copy():
player.move_item_between_inventory_types(None, inventory_type_a=InventoryType.TempModels, inventory_type_b=InventoryType.Models, object_id=model.object_id, stack_count=0)
def modular_build_move_and_equip(self, address, template_id:c_int=None):
player = self._v_server.accounts[address].characters.selected()
new_item = player.move_item_between_inventory_types(None, inventory_type_a=InventoryType.TempModels, inventory_type_b=InventoryType.Models, object_id=0, template_id=template_id)
player.equip_inventory(None, item_to_equip=new_item.object_id)
def modular_build_finish(self, address, module_lots:(c_ubyte, c_int)=None):
player = self._v_server.accounts[address].characters.selected()
for model in player.temp_models.copy():

View File

@@ -40,5 +40,5 @@ class PetComponent:
if mission.state == MissionState.Active:
for task in mission.tasks:
if task.type == TaskType.TamePet and self.lot in task.target:
mission.increment_task(task, self._v_server, player)
mission.increment_task(task, player)

View File

@@ -1,7 +1,9 @@
import asyncio
import time
from ..bitstream import c_bit, c_float, c_int, c_int64, c_uint
from ..math.vector import Vector3
from .char import TerminateType
from .mission import MissionState, TaskType
from .scripted_activity import ScriptedActivityComponent
@@ -10,6 +12,7 @@ class RebuildState:
Completed = 2
Resetting = 4
Building = 5
Incomplete = 6
class FailReason:
NotGiven = 0
@@ -22,19 +25,31 @@ class RebuildComponent(ScriptedActivityComponent):
super().__init__(comp_id)
self.complete_time = self._v_server.db.rebuild_component[comp_id][0]
self.smash_time = self._v_server.db.rebuild_component[comp_id][1]
self.reset_time = self._v_server.db.rebuild_component[comp_id][2]
self.imagination_cost = self._v_server.db.rebuild_component[comp_id][3]
self.callback_handles = []
self.rebuild_start_time = 0
self.last_progress = 0
self._flags["rebuild_state"] = "rebuild_flag"
self._flags["success"] = "rebuild_flag"
self._flags["enabled"] = "rebuild_flag"
self._flags["rebuild_duration"] = "rebuild_flag"
self.rebuild_state = RebuildState.Open
self._rebuild_state = RebuildState.Open
self.success = False
self.enabled = True
self.rebuild_duration = 0
if not hasattr(self, "rebuild_activator_position"):
self.rebuild_activator_position = Vector3(self.position)
@property
def rebuild_state(self):
return self._rebuild_state
@rebuild_state.setter
def rebuild_state(self, value):
player = self._v_server.get_object(self.players[0])
self._v_server.send_game_message(self.rebuild_notify_state, self.rebuild_state, value, player=player.object_id, address=player.address)
self._rebuild_state = value
def serialize(self, out, is_creation):
super().serialize(out, is_creation)
out.write(c_bit(self.rebuild_flag or is_creation))
@@ -42,7 +57,7 @@ class RebuildComponent(ScriptedActivityComponent):
out.write(c_uint(self.rebuild_state))
out.write(c_bit(self.success))
out.write(c_bit(self.enabled))
out.write(c_float(self.rebuild_duration))
out.write(c_float(time.time() - self.rebuild_start_time))
out.write(c_uint(0))
if is_creation:
out.write(c_bit(False))
@@ -53,29 +68,36 @@ class RebuildComponent(ScriptedActivityComponent):
self.rebuild_flag = False
def on_use(self, player, multi_interact_id):
if self.rebuild_state == RebuildState.Open:
assert multi_interact_id is None
prev_state = self.rebuild_state
self.rebuild_state = RebuildState.Building
self.players.append(player.object_id)
self.activity_flag = True
player.rebuilding = 1
self._v_server.send_game_message(self.rebuild_notify_state, prev_state, self.rebuild_state, player=player.object_id, address=player.address)
self._v_server.send_game_message(self.enable_rebuild, enable=True, fail=False, success=False, duration=0, user=player.object_id, address=player.address)
assert multi_interact_id is None
assert self.rebuild_state in (RebuildState.Open, RebuildState.Incomplete)
for handle in self.callback_handles:
handle.cancel()
self.callback_handles.clear()
self.players.append(player.object_id)
self.activity_flag = True
self.rebuild_state = RebuildState.Building
player.rebuilding = 1
self._v_server.send_game_message(self.enable_rebuild, enable=self.enabled, fail=False, success=self.success, duration=0, user=player.object_id, address=player.address)
self.rebuild_start_time = time.time()
drain_interval = self.complete_time/self.imagination_cost
remaining_cost = int((self.complete_time - self.last_progress) // drain_interval)
for i in range(remaining_cost):
self.callback_handles.append(asyncio.get_event_loop().call_later(self.last_progress%drain_interval + drain_interval*i, self.drain_imagination, player))
self.callback_handles.append(asyncio.get_event_loop().call_later(self.complete_time-self.last_progress, self.complete_rebuild, player))
return True
asyncio.get_event_loop().call_later(self.complete_time, self.complete_rebuild, player)
return True
def drain_imagination(self, player):
player.imagination -= 1
if player.imagination == 0:
self.rebuild_cancel(None, early_release=False, user_id=player.object_id)
def complete_rebuild(self, player):
prev_state = self.rebuild_state
self.rebuild_state = RebuildState.Completed
self.success = True
self.enabled = False
self.rebuild_duration = self.complete_time
player.rebuilding = 0
self._v_server.send_game_message(self.rebuild_notify_state, prev_state, self.rebuild_state, player=player.object_id, address=player.address)
self._v_server.send_game_message(self.enable_rebuild, enable=False, fail=False, success=True, duration=0, user=player.object_id, address=player.address)
self._v_server.send_game_message(self.enable_rebuild, enable=self.enabled, fail=False, success=self.success, duration=0, user=player.object_id, address=player.address)
self._v_server.send_game_message(self.play_f_x_effect, name="BrickFadeUpVisCompleteEffect", effect_type="create", effect_id=507, address=player.address)
self._v_server.send_game_message(player.play_animation, animation_id="rebuild-celebrate", play_immediate=False, address=player.address)
assert len(self.children) == 1
@@ -87,16 +109,30 @@ class RebuildComponent(ScriptedActivityComponent):
if mission.state == MissionState.Active:
for task in mission.tasks:
if task.type == TaskType.QuickBuild and task.target == self.lot:
mission.increment_task(task, self._v_server, player)
mission.increment_task(task, player)
def smash_rebuild(self):
self._v_server.send_game_message(self.die, death_type="", direction_relative_angle_xz=0, direction_relative_angle_y=0, direction_relative_force=10, killer_id=0, broadcast=True)
self._v_server.destruct(self)
def rebuild_cancel(self, address, early_release:c_bit=None, user_id:c_int64=None):
pass#self.rebuild_state = RebuildState.Open
#self.players.remove(user_id)
#self.activity_flag = True
player = self._v_server.get_object(user_id)
if self.rebuild_state == RebuildState.Building:
for handle in self.callback_handles:
handle.cancel()
self.callback_handles.clear()
self.last_progress += time.time() - self.rebuild_start_time
self.rebuild_state = RebuildState.Incomplete
self.players.remove(user_id)
self.activity_flag = True
player.rebuilding = 0
if early_release:
fail_reason = FailReason.CanceledEarly
else:
fail_reason = FailReason.OutOfImagination
self._v_server.send_game_message(self.enable_rebuild, enable=False, fail=True, success=self.success, fail_reason=fail_reason, duration=self.last_progress, user=player.object_id, address=player.address)
self.callback_handles.append(asyncio.get_event_loop().call_later(self.reset_time, self.smash_rebuild))
self._v_server.send_game_message(player.terminate_interaction, obj_id_terminator=self.object_id, type=TerminateType.FromInteraction, address=player.address)
def enable_rebuild(self, address, enable:c_bit=None, fail:c_bit=None, success:c_bit=None, fail_reason:c_uint=FailReason.NotGiven, duration:c_float=None, user:c_int64=None):
pass

View File

@@ -123,7 +123,7 @@ class SkillComponent:
if mission.state == MissionState.Active:
for task in mission.tasks:
if task.type == TaskType.UseSkill and skill_id in task.parameter:
mission.increment_task(task, self._v_server, self)
mission.increment_task(task, self)
target = self
self.picked_target_id = optional_target_id

View File

@@ -1,6 +1,8 @@
import asyncio
import random
from ..bitstream import c_bit, c_float, c_int, c_int64, c_uint
from ..math.vector import Vector3
class StatsSubcomponent:
def __init__(self, comp_id):
@@ -16,7 +18,7 @@ class StatsSubcomponent:
self.life = self.max_life
self.armor = self.max_armor
self.imagination = self.max_imagination
self.is_smashable = False
@property
def max_life(self):
@@ -93,12 +95,11 @@ class StatsSubcomponent:
out.write(c_float(self.max_imagination))
out.write(c_uint(1))
out.write(c_int(self.faction))
show_smashable_glint = True
out.write(c_bit(show_smashable_glint))
out.write(c_bit(self.is_smashable))
if is_creation:
out.write(c_bit(False))
out.write(c_bit(False))
if show_smashable_glint:
if self.is_smashable:
out.write(c_bit(False))
out.write(c_bit(False))
@@ -110,5 +111,10 @@ class StatsSubcomponent:
if self.spawner is not None:
asyncio.get_event_loop().call_later(8, self.spawner.spawn)
def drop_loot(self, lot, owner):
object_id = self._v_server.new_spawned_id()
self._v_server.dropped_loot.setdefault(owner.object_id, {})[object_id] = lot
self._v_server.send_game_message(owner.drop_client_loot, use_position=True, spawn_position=self.position, final_position=Vector3(self.position.x+(random.random()-0.5)*20, self.position.y, self.position.z+(random.random()-0.5)*20), currency=0, item_template=lot, loot_id=object_id, owner=owner.object_id, source_obj=self.object_id, address=owner.address)
def die(self, address, client_death:c_bit=False, spawn_loot:c_bit=True, death_type:"wstr"=None, direction_relative_angle_xz:c_float=None, direction_relative_angle_y:c_float=None, direction_relative_force:c_float=None, kill_type:c_uint=0, killer_id:c_int64=None, loot_owner_id:c_int64=0):
pass

View File

@@ -32,7 +32,7 @@ class VendorComponent:
player = self._v_server.accounts[address].characters.selected()
for item in player.items:
if item is not None and item.object_id == item_obj_id:
self._v_server.send_game_message(player.set_currency, currency=player.currency + (item.base_value*count)//10, position=Vector3.zero, source_type=source_type, address=player.address)
self._v_server.send_game_message(player.set_currency, currency=player.currency + (item.base_value*count)//10, position=Vector3.zero, address=player.address)
player.remove_item_from_inv(InventoryType.Items, object_id=item_obj_id, amount=count)
break
else:

View File

@@ -59,7 +59,6 @@ component[65] = PropertyVendorComponent,
component[67] = LaunchpadComponent,
component[104] = RailActivatorComponent,
component_order = list(component.keys())
def restore_template(*args):
@@ -83,8 +82,11 @@ def Template(lot_, conn=None, comps=None, custom_script=None):
for component_type, component_id in sorted(comp_ids, key=lambda x: component_order.index(x[0]) if x[0] in component_order else 99999):
if component_type == 5:
if component_id is None:
script = importlib.import_module("luserver.scripts."+custom_script)
comp = script.ScriptComponent,
if custom_script != "":
script = importlib.import_module("luserver.scripts."+custom_script)
comp = script.ScriptComponent,
else:
comp = ScriptComponent,
elif component_id in conn.root.script_component:
script = importlib.import_module("luserver.scripts."+conn.root.script_component[component_id])
comp = script.ScriptComponent,
@@ -213,7 +215,7 @@ def Template(lot_, conn=None, comps=None, custom_script=None):
if mission.state == MissionState.Active:
for task in mission.tasks:
if task.type == TaskType.UseEmote and emote_id in task.parameter and task.target == self._v_server.game_objects[target_id].lot:
mission.increment_task(task, self._v_server, self)
mission.increment_task(task, self)
def play_animation(self, address, animation_id:"wstr"=None, expect_anim_to_exist:c_bit=True, play_immediate:c_bit=None, trigger_on_complete_msg:c_bit=False, priority:c_float=2, f_scale:c_float=1):

View File

@@ -119,6 +119,7 @@ class GameMessage(Enum):
NotifyMission = 254
NotifyMissionTask = 255
RebuildNotifyState = 336
TerminateInteraction = 357
RequestUse = 364
VendorOpenWindow = 369
EmotePlayed = 371
@@ -168,9 +169,11 @@ class GameMessage(Enum):
StartBuildingWithItem = 1057
StartArrangingWithItem = 1061
FinishArrangingWithItem = 1062
DoneArrangingWithItem = 1063
SetBuildMode = 1068
SetBuildModeConfirmed = 1073
MoveItemBetweenInventoryTypes = 1093
ModularBuildMoveAndEquip = 1096
ModularBuildFinish = 1097
EchoSyncSkill = 1144
SyncSkill = 1145

View File

@@ -102,6 +102,9 @@ class ChatHandling(ServerModule):
build_cmd.add_argument("type", type=int)
build_cmd.set_defaults(func=self.build_cmd)
check_for_leaks_cmd = cmds.add_parser("checkforleaks")
check_for_leaks_cmd.set_defaults(func=self.check_for_leaks_cmd)
complete_mission_cmd = cmds.add_parser("completemission")
complete_mission_cmd.add_argument("--id", type=int)
complete_mission_cmd.set_defaults(func=self.complete_mission_cmd)
@@ -119,6 +122,9 @@ class ChatHandling(ServerModule):
faction_cmd.add_argument("faction", type=int)
faction_cmd.set_defaults(func=self.faction_cmd)
glow_cmd = cmds.add_parser("glow")
glow_cmd.set_defaults(func=self.glow_cmd)
filelog_cmd = cmds.add_parser("filelog", description="Change which packets are logged to file")
filelog_cmd.add_argument("action", choices=("add", "remove", "show"), default="show")
filelog_cmd.add_argument("packetname")
@@ -280,6 +286,9 @@ class ChatHandling(ServerModule):
def build_cmd(self, args, sender):
self.server.send_game_message(sender.activate_brick_mode, build_type=args.type, address=sender.address)
def check_for_leaks_cmd(self, args, sender):
sender.check_for_leaks()
def complete_mission_cmd(self, args, sender):
if args.id:
for mission in sender.missions:
@@ -290,7 +299,7 @@ class ChatHandling(ServerModule):
if mission.state == 2:
for task_index, task_data in enumerate(self.server.db.missions[mission.id][2]):
target_value = task_data[2]
mission.increment_task(mission.tasks[task_index], self.server, sender, target_value)
mission.increment_task(mission.tasks[task_index], sender, target_value)
self.server.commit()
def dismount_cmd(self, args, sender):
@@ -313,6 +322,12 @@ class ChatHandling(ServerModule):
elif args.action == "show":
print(self.server.file_logged_packets)
def glow_cmd(self, args, sender):
if sender.rebuilding == 0:
sender.rebuilding = 1
else:
sender.rebuilding = 0
def help_cmd(self, args, sender):
print("Please use -h / --help for help.")

View File

@@ -11,7 +11,7 @@ MODEL_DIMENSIONS[5633] = Vector3(-819.2, 0, -819.2), Vector3(819.2, 13.521, 819.
MODEL_DIMENSIONS[5652] = Vector3(-2.5, -2.5, -2.5), Vector3(2.5, 2.5, 2.5)
MODEL_DIMENSIONS[8419] = Vector3(-5.2644, 0.0051, -0.5011), Vector3(4.7356, 5.0051, 0.4989)
DEBUG_INCLUDE_NO_SCRIPT = True
DEBUG_INCLUDE_NO_SCRIPT = False
log = logging.getLogger(__file__)

View File

@@ -0,0 +1,4 @@
import luserver.components.script as script
class ScriptComponent(script.ScriptComponent):
pass # currently not implemented

View File

@@ -17,4 +17,4 @@ class ScriptComponent(script.ScriptComponent):
if mission.state == MissionState.Active and mission.id == achievement_id:
for task in mission.tasks:
if task.type == TaskType.Script and self.lot in task.target:
mission.increment_task(task, self._v_server, player)
mission.increment_task(task, player)

View File

@@ -7,4 +7,4 @@ class ScriptComponent(script.ScriptComponent):
if mission.state == MissionState.Active and mission.id == self.script_vars["touch_complete_mission_id"]:
for task in mission.tasks:
if task.type == TaskType.Script and self.lot in task.target:
mission.increment_task(task, self._v_server, player)
mission.increment_task(task, player)

View File

@@ -0,0 +1,14 @@
import asyncio
import luserver.components.script as script
from luserver.components.rebuild import RebuildComponent
IMAGINATION_POWERUP_LOT = 935
SPAWN_AMOUNT = 10
SPAWN_INTERVAL = 1.5
class ScriptComponent(script.ScriptComponent):
def complete_rebuild(self, player):
RebuildComponent.complete_rebuild(self, player)
for i in range(SPAWN_AMOUNT):
asyncio.get_event_loop().call_later(i*SPAWN_INTERVAL, self.drop_loot, IMAGINATION_POWERUP_LOT, player)

View File

@@ -34,5 +34,5 @@ class ScriptComponent(script.ScriptComponent):
for achievement_id in achievements:
for mission in player.missions:
if mission.id == achievement_id:
mission.complete(self._v_server, player)
mission.complete(player)
break

View File

@@ -11,5 +11,5 @@ class ScriptComponent(script.ScriptComponent):
player.imagination = 6
for mission in player.missions:
if mission.id == 664:
mission.complete(self._v_server, player)
mission.complete(player)
break

View File

@@ -116,8 +116,6 @@ class WorldServer(server.Server, pyraknet.replicamanager.ReplicaManager):
console_log = packetname not in self.not_console_logged_packets
except ValueError:
packetname = self.unknown_packetname(data)
with open("logs/"+packetname+".bin", "wb") as file:
file.write(data)
console_log = True
if console_log:

View File

@@ -79,7 +79,6 @@ def get_behavior(behavior_id):
if behavior_id not in root.behavior:
global behavs_accessed
behavs_accessed += 1
print(behavior_id)
if behavior_id not in templates:
return None
template_id = templates[behavior_id]
@@ -311,7 +310,7 @@ if GENERATE_COMPS:
root.script_component[id] = script_name
elif row[1] == 7 and row[2] not in root.destructible_component:
faction, faction_list, level, loot_matrix_index, currency_index, life, armor, imagination = cdclient.execute("select faction, factionList, level, LootMatrixIndex, CurrencyIndex, life, armor, imagination from DestructibleComponent where id == %i" % row[2]).fetchone()
faction, faction_list, level, loot_matrix_index, currency_index, life, armor, imagination, is_smashable = cdclient.execute("select faction, factionList, level, LootMatrixIndex, CurrencyIndex, life, armor, imagination, isSmashable from DestructibleComponent where id == %i" % row[2]).fetchone()
if faction is None:
faction = int(faction_list) # fallback, i have no idea why both columns exist in the first place
if level is not None and currency_index is not None:
@@ -332,7 +331,7 @@ if GENERATE_COMPS:
if armor is not None:
armor = int(armor)
root.destructible_component[row[2]] = faction, loot, minvalue, maxvalue, life, armor, imagination
root.destructible_component[row[2]] = faction, loot, minvalue, maxvalue, life, armor, imagination, is_smashable
elif row[1] == 16 and row[2] not in root.vendor_component:
comp_row = cdclient.execute("select LootMatrixIndex from VendorComponent where id == %i" % row[2]).fetchone()
@@ -344,12 +343,12 @@ if GENERATE_COMPS:
root.inventory_component.setdefault(row[2], []).append((comp_row[0], comp_row[1]))
elif row[1] == 48 and row[2] not in root.rebuild_component:
comp_row = cdclient.execute("select complete_time, time_before_smash from RebuildComponent where id == %i" % row[2]).fetchone()
comp_row = cdclient.execute("select complete_time, time_before_smash, reset_time, take_imagination from RebuildComponent where id == %i" % row[2]).fetchone()
if comp_row is not None:
complete_time, smash_time = comp_row
complete_time, smash_time, reset_time, take_imagination = comp_row
if complete_time is None:
complete_time = 0
root.rebuild_component[row[2]] = complete_time, smash_time
root.rebuild_component[row[2]] = complete_time, smash_time, reset_time, take_imagination
elif row[1] == 53 and row[2] not in root.package_component:
comp_row = cdclient.execute("select LootMatrixIndex from PackageComponent where id == %i" % row[2]).fetchone()

View File

@@ -94,8 +94,11 @@ def parse_lvl(conn, world_data, lvl_path):
config = ldf.from_ldf(config_data)
custom_script = None
if lot != 176 and config.get("custom_script_server") not in (None, ""):
custom_script = scripts.SCRIPTS.get(config["custom_script_server"][len("scripts\\"):])
if lot != 176 and "custom_script_server" in config:
if config["custom_script_server"] == "":
custom_script = ""
else:
custom_script = scripts.SCRIPTS.get(config["custom_script_server"][len("scripts\\"):])
spawned_vars = {}
if "groupID" in config:
@@ -135,8 +138,11 @@ def parse_lvl(conn, world_data, lvl_path):
spawn_vars = {}
obj.spawntemplate = config["spawntemplate"]
if config.get("custom_script_server") not in (None, ""):
spawn_vars["custom_script"] = scripts.SCRIPTS.get(config["custom_script_server"][len("scripts\\"):])
if "custom_script_server" in config:
if config["custom_script_server"] == "":
spawn_vars["custom_script"] = ""
else:
spawn_vars["custom_script"] = scripts.SCRIPTS.get(config["custom_script_server"][len("scripts\\"):])
if "attached_path" in config:
spawned_vars["attached_path"] = config["attached_path"]

View File

@@ -1,4 +1,5 @@
# consider converting all to path
# consider converting all to path so components using the same script are automatically handled
# some paths are removed from the database though
SCRIPTS = {}
SCRIPTS[313] = "general.death_trigger"
@@ -34,7 +35,9 @@ SCRIPTS[r"02_server\Map\General\L_TOUCH_MISSION_UPDATE_SERVER.lua"] = "general.t
SCRIPTS[r"02_server\Map\NT\L_NT_PARADOXTELE_SERVER.lua"] = "nexus_tower.paradox_teleporter"
SCRIPTS[r"ai\AG\L_ACT_SHARK_PLAYER_DEATH_TRIGGER.lua"] = "general.shark_death_trigger"
SCRIPTS[r"ai\AG\L_AG_PICNIC_BLANKET.lua"] = "avant_gardens.picnic_blanket"
SCRIPTS[r"ai\AG\L_AG_QB_Elevator.lua"] = "avant_gardens.quickbuild_elevator"
SCRIPTS[r"ai\AG\L_AG_SHIP_PLAYER_DEATH_TRIGGER.lua"] = "venture_explorer.death_trigger"
SCRIPTS[r"ai\AG\L_AG_SHIP_PLAYER_SHOCK_SERVER.lua"] = "venture_explorer.broken_console"
SCRIPTS[r"ai\AG\L_AG_SHIP_SHAKE.lua"] = "venture_explorer.ship_shake"
SCRIPTS[r"ai\NS\L_NS_JONNY_FLAG_MISSION_SERVER.lua"] = "nimbus_station.johnny_thunder"
SCRIPTS[r"ai\NS\L_NS_QB_IMAGINATION_STATUE.lua"] = "nimbus_station.imagination_statue"