4 Commits
0.4 ... 0.6.0

Author SHA1 Message Date
d4dd9b5919 0.6.0 2024-11-08 03:58:34 -06:00
65f66921a9 0.6 features 2024-11-08 03:54:34 -06:00
0460ca99d6 0.5.1 2024-11-07 14:27:55 -06:00
cb418f547d 0.5 update 2024-11-07 01:05:45 -06:00
6 changed files with 924 additions and 1064 deletions

View File

@@ -24,3 +24,23 @@ initial release
- bbcode enabled globally - bbcode enabled globally
- intrusive bbcode separated - intrusive bbcode separated
- custom name bbcode - custom name bbcode
0.5
----
- update to webfishing 1.09
- bbcode stuff only to lucystools users
- intrusive bbcode now client toggle
- lots of stuff removed due to 1.09 having it already!
- panel stays closed if closed, open if open
0.5.1
----
- Lure 4.1.0 compatibility
- log fixes
- spawn fixes
0.6.0
----
- custom text color (bbcode qol)
- experimental color bug bbcode
- better (actually somewhat working) bbcode filtering

View File

@@ -6,34 +6,34 @@ func setup():
get_node("%lucy_bbcode").pressed = MANAGER.allow_bbcode get_node("%lucy_bbcode").pressed = MANAGER.allow_bbcode
get_node("%lucy_punchback").pressed = MANAGER.do_punchback get_node("%lucy_punchback").pressed = MANAGER.do_punchback
get_node("%lucy_servername").text = MANAGER.custom_server_name get_node("%lucy_servername").text = MANAGER.custom_server_name
get_node("%lucy_servername_preview").bbcode_text = MANAGER.custom_server_name + "'s Lobby" get_node("%lucy_servername_preview").bbcode_text = MANAGER.custom_server_name
get_node("%lucy_servermsg").text = MANAGER.server_join_message get_node("%lucy_servermsg").text = MANAGER.server_join_message
get_node("%lucy_servermsg_preview").bbcode_text = MANAGER.server_join_message var srv_m_bb = MANAGER.bbcode_process(MANAGER.server_join_message, 512)
get_node("%lucy_fpackets").value = MANAGER.frame_packets get_node("%lucy_servermsg_preview").bbcode_text = srv_m_bb.fin
get_node("%lucy_bpackets").value = MANAGER.bulk_packets get_node("%lucy_servermsg_preview2").bbcode_text = srv_m_bb.stripped
get_node("%lucy_binterval").value = MANAGER.bulk_interval
get_node("%lucy_finterval").value = MANAGER.full_interval
get_node("%lucy_intbbcode").pressed = MANAGER.allow_intrusive_bbcode get_node("%lucy_intbbcode").pressed = MANAGER.allow_intrusive_bbcode
get_node("%lucy_chatcolor_bool").pressed = MANAGER.custom_color_enabled get_node("%lucy_chatcolor_bool").pressed = MANAGER.custom_color_enabled
get_node("%lucy_chatcolor").color = Color(MANAGER.custom_color) get_node("%lucy_chatcolor").color = Color(MANAGER.custom_color)
get_node("%lucy_chatcolor_bool2").pressed = MANAGER.custom_text_color_enabled
get_node("%lucy_chatcolor2").color = Color(MANAGER.custom_text_color)
get_node("%lucy_name").text = MANAGER.custom_name get_node("%lucy_name").text = MANAGER.custom_name
get_node("%lucy_bug_bb").pressed = MANAGER.bug_bbcode
get_node("%lucy_srv_bbcode").pressed = MANAGER.srv_bbcode
update() update()
func update(): func update():
get_node("%lucy_srv_allow_bbcode").text = "Yes" if MANAGER.srv_allow_bbcode else "No"
_on_lucy_name_text_changed(MANAGER.custom_name) _on_lucy_name_text_changed(MANAGER.custom_name)
func _on_lucy_name_text_changed(new_text): func _on_lucy_name_text_changed(new_text):
var result = MANAGER.bbcode_process(new_text) var result = MANAGER.bbcode_process(new_text, 512)
#print("[fin] ", result.fin)
#print("[tags] ", result.tags)
#print("[stripped] ", result.stripped)
var lol_steam_username = Network.STEAM_USERNAME.replace("[", "").replace("]", "") var lol_steam_username = Network.STEAM_USERNAME.replace("[", "").replace("]", "")
var good = result.stripped == lol_steam_username var good = result.stripped == lol_steam_username
@@ -41,31 +41,39 @@ func _on_lucy_name_text_changed(new_text):
get_node("%lucy_namegood").bbcode_text = "[color=green]Good[/color]" if good else "[color=red]Bad[/color]" get_node("%lucy_namegood").bbcode_text = "[color=green]Good[/color]" if good else "[color=red]Bad[/color]"
MANAGER.custom_name_enabled = good MANAGER.custom_name_enabled = good
MANAGER.custom_name = result.fin MANAGER.custom_name = new_text
func _ready(): func _ready():
print("[LUCY] Menu Ready") print("[LUCY] Menu Ready")
MANAGER = $"/root/LucyLucysTools" MANAGER = $"/root/LucyLucysTools"
get_node("%lucy_bbcode").disabled = MANAGER.host_required and not Network.GAME_MASTER visible = MANAGER.lucys_menu_visible
get_node("%lucy_raincloud").disabled = not Network.GAME_MASTER or not MANAGER.ingame
get_node("%lucy_meteor").disabled = not Network.GAME_MASTER or not MANAGER.ingame var can_spawn = (Network.GAME_MASTER or Network.PLAYING_OFFLINE) and MANAGER.ingame
get_node("%lucy_freezerain").disabled = not Network.GAME_MASTER or not MANAGER.ingame
get_node("%lucy_clearrain").disabled = not Network.GAME_MASTER or not MANAGER.ingame get_node("%lucy_raincloud").disabled = not can_spawn
get_node("%lucy_clearmeteor").disabled = not Network.GAME_MASTER or not MANAGER.ingame get_node("%lucy_meteor").disabled = not can_spawn
get_node("%lucy_freezerain").disabled = not can_spawn
get_node("%lucy_clearrain").disabled = not can_spawn
get_node("%lucy_clearmeteor").disabled = not can_spawn
get_node("%lucy_srv_bbcode").disabled = not (Network.GAME_MASTER or Network.PLAYING_OFFLINE)
func _input(event): func _input(event):
if event is InputEventKey and event.scancode == KEY_F5 && event.pressed: if event is InputEventKey and event.scancode == KEY_F5 && event.pressed:
visible = !visible visible = !visible
print("[LUCY] Menu visble: ", visible) print("[LUCY] Menu visble: ", visible)
MANAGER.lucys_menu_visible = visible
if event is InputEventKey and event.scancode == KEY_F6 && event.pressed: if event is InputEventKey and event.scancode == KEY_F6 && event.pressed:
var name = Steam.getLobbyData(Network.STEAM_LOBBY_ID, "name") var name = Steam.getLobbyData(Network.STEAM_LOBBY_ID, "name")
var lname = Steam.getLobbyData(Network.STEAM_LOBBY_ID, "lobby_name")
var nm = Steam.getNumLobbyMembers(Network.STEAM_LOBBY_ID) var nm = Steam.getNumLobbyMembers(Network.STEAM_LOBBY_ID)
var code = Steam.getLobbyData(Network.STEAM_LOBBY_ID, "code") var code = Steam.getLobbyData(Network.STEAM_LOBBY_ID, "code")
var type = Steam.getLobbyData(Network.STEAM_LOBBY_ID, "type") var type = Steam.getLobbyData(Network.STEAM_LOBBY_ID, "type")
var lobby_dat = {"name": name, "nm": nm, "code": code, "type": type} var bbname = Steam.getLobbyData(Network.STEAM_LOBBY_ID, "bbcode_lobby_name")
var lobby_dat = {"name": name, "lobby_name":lname, "bbcode_lobby_name":bbname, "nm": nm, "code": code, "type": type}
print("[LUCY] LOBBY ", lobby_dat) print("[LUCY] LOBBY ", lobby_dat)
func _on_lucy_bbcode_toggled(button_pressed): func _on_lucy_bbcode_toggled(button_pressed):
@@ -73,28 +81,31 @@ func _on_lucy_bbcode_toggled(button_pressed):
func _on_lucy_punchback_toggled(button_pressed): func _on_lucy_punchback_toggled(button_pressed):
MANAGER.do_punchback = button_pressed MANAGER.do_punchback = button_pressed
func _on_lucy_servername_text_changed(new_text): func _on_lucy_servername_text_changed(new_text):
get_node("%lucy_servername_preview").bbcode_text = new_text + "'s Lobby" get_node("%lucy_servername_preview").bbcode_text = new_text
MANAGER.custom_server_name = new_text MANAGER.custom_server_name = new_text
func _on_lucy_servermsg_text_changed(new_text): func _on_lucy_servermsg_text_changed(new_text):
get_node("%lucy_servermsg_preview").bbcode_text = new_text var result = MANAGER.bbcode_process(new_text, 512)
get_node("%lucy_servermsg_preview").bbcode_text = result.fin
get_node("%lucy_servermsg_preview2").bbcode_text = result.stripped
MANAGER.server_join_message = new_text MANAGER.server_join_message = new_text
func _on_lucy_fpackets_value_changed(value):
MANAGER.frame_packets = value
func _on_lucy_bpackets_value_changed(value):
MANAGER.bulk_packets = value
func _on_lucy_binterval_value_changed(value):
MANAGER.bulk_interval = value
func _on_lucy_finterval_value_changed(value):
MANAGER.full_interval = value
func _on_lucy_chatcolor_bool_toggled(button_pressed): func _on_lucy_chatcolor_bool_toggled(button_pressed):
MANAGER.custom_color_enabled = button_pressed MANAGER.custom_color_enabled = button_pressed
func _on_lucy_chatcolor_color_changed(color): func _on_lucy_chatcolor_color_changed(color):
MANAGER.custom_color = color MANAGER.custom_color = color
func _on_lucy_chatcolor_bool2_toggled(button_pressed):
MANAGER.custom_text_color_enabled = button_pressed
func _on_lucy_chatcolor2_color_changed(color):
MANAGER.custom_text_color = color
func _on_lucy_intbbcode_toggled(button_pressed): func _on_lucy_intbbcode_toggled(button_pressed):
MANAGER.allow_intrusive_bbcode = button_pressed MANAGER.allow_intrusive_bbcode = button_pressed
func _on_lucy_bug_bb_toggled(button_pressed):
MANAGER.bug_bbcode = button_pressed
func _on_lucy_srv_bbcode_toggled(button_pressed):
if (not Network.GAME_MASTER and not Network.PLAYING_OFFLINE): return
MANAGER.srv_bbcode = button_pressed
func _on_lucy_raincloud_pressed(): func _on_lucy_raincloud_pressed():
if not MANAGER.ingame: return if not MANAGER.ingame or (not Network.GAME_MASTER and not Network.PLAYING_OFFLINE): return
print("[LUCY] Spawning raincloud") print("[LUCY] Spawning raincloud")
var player = MANAGER.get_player() var player = MANAGER.get_player()
var pos = Vector3(player.global_transform.origin.x, 42, player.global_transform.origin.z) var pos = Vector3(player.global_transform.origin.x, 42, player.global_transform.origin.z)
@@ -102,7 +113,7 @@ func _on_lucy_raincloud_pressed():
Network._sync_create_actor("raincloud", pos, zone, - 1, Network.STEAM_ID) Network._sync_create_actor("raincloud", pos, zone, - 1, Network.STEAM_ID)
func _on_lucy_meteor_pressed(): func _on_lucy_meteor_pressed():
if not MANAGER.ingame: return if not MANAGER.ingame or (not Network.GAME_MASTER and not Network.PLAYING_OFFLINE): return
if get_tree().get_nodes_in_group("meteor").size() > 10: return if get_tree().get_nodes_in_group("meteor").size() > 10: return
print("[LUCY] Spawning meteor") print("[LUCY] Spawning meteor")
var player_pos = MANAGER.get_player().global_transform.origin var player_pos = MANAGER.get_player().global_transform.origin
@@ -118,7 +129,7 @@ func _on_lucy_meteor_pressed():
Network._sync_create_actor("fish_spawn_alien", pos, zone, - 1, Network.STEAM_ID) Network._sync_create_actor("fish_spawn_alien", pos, zone, - 1, Network.STEAM_ID)
func _on_lucy_freezerain_pressed(): func _on_lucy_freezerain_pressed():
if not MANAGER.ingame or not Network.GAME_MASTER: return if not MANAGER.ingame or (not Network.GAME_MASTER and not Network.PLAYING_OFFLINE): return
print("[LUCY] Freezing rain") print("[LUCY] Freezing rain")
for cloud in get_tree().get_nodes_in_group("raincloud"): for cloud in get_tree().get_nodes_in_group("raincloud"):
if cloud.controlled == true: if cloud.controlled == true:
@@ -126,18 +137,17 @@ func _on_lucy_freezerain_pressed():
cloud.decay = false cloud.decay = false
func _on_lucy_clearrain_pressed(): func _on_lucy_clearrain_pressed():
if not MANAGER.ingame or not Network.GAME_MASTER: return if not MANAGER.ingame or (not Network.GAME_MASTER and not Network.PLAYING_OFFLINE): return
print("[LUCY] Clearing rain") print("[LUCY] Clearing rain")
for cloud in get_tree().get_nodes_in_group("raincloud"): for cloud in get_tree().get_nodes_in_group("raincloud"):
cloud._deinstantiate(true) cloud._deinstantiate(true)
func _on_lucy_clearchat_pressed(): func _on_lucy_clearchat_pressed():
Network.GAMECHAT = "" Network._wipe_chat()
Network.LOCAL_GAMECHAT = ""
Network.emit_signal("_chat_update") Network.emit_signal("_chat_update")
func _on_lucy_clearmeteor_pressed(): func _on_lucy_clearmeteor_pressed():
if not MANAGER.ingame or not Network.GAME_MASTER: return if not MANAGER.ingame or (not Network.GAME_MASTER and not Network.PLAYING_OFFLINE): return
print("[LUCY] Clearing meteor") print("[LUCY] Clearing meteor")
for meteor in get_tree().get_nodes_in_group("meteor"): for meteor in get_tree().get_nodes_in_group("meteor"):
meteor._deinstantiate(true) meteor._deinstantiate(true)

View File

@@ -4,112 +4,136 @@
[node name="lucys_menu" type="Control"] [node name="lucys_menu" type="Control"]
margin_right = 800.0 margin_right = 800.0
margin_bottom = 329.0 margin_bottom = 400.0
script = ExtResource( 1 ) script = ExtResource( 1 )
[node name="PanelContainer" type="PanelContainer" parent="."] [node name="PanelContainer" type="PanelContainer" parent="."]
anchor_right = 1.0 anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
margin_bottom = 71.0 margin_bottom = 100.0
[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer"] [node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer"]
margin_left = 7.0 margin_left = 7.0
margin_top = 7.0 margin_top = 7.0
margin_right = 793.0 margin_right = 793.0
margin_bottom = 393.0 margin_bottom = 493.0
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer"] [node name="Label" type="Label" parent="PanelContainer/VBoxContainer"]
margin_right = 786.0 margin_right = 786.0
margin_bottom = 14.0 margin_bottom = 14.0
text = "Lucy's Options - F5 to Toggle Menu" text = "Lucy's Options 0.6.0 - F5 to Toggle Menu"
[node name="HSeparator" type="HSeparator" parent="PanelContainer/VBoxContainer"] [node name="HSeparator" type="HSeparator" parent="PanelContainer/VBoxContainer"]
margin_top = 18.0 margin_top = 18.0
margin_right = 786.0 margin_right = 786.0
margin_bottom = 22.0 margin_bottom = 22.0
[node name="HFlowContainer" type="HFlowContainer" parent="PanelContainer/VBoxContainer"] [node name="Label4" type="Label" parent="PanelContainer/VBoxContainer"]
margin_top = 26.0 margin_top = 26.0
margin_right = 786.0 margin_right = 786.0
margin_bottom = 66.0 margin_bottom = 40.0
text = "BBCode is only visible to LucysTools-compatible users, unless Bug BBCode is enabled"
[node name="HFlowContainer" type="HFlowContainer" parent="PanelContainer/VBoxContainer"]
margin_top = 44.0
margin_right = 786.0
margin_bottom = 84.0
rect_pivot_offset = Vector2( -141, -49 ) rect_pivot_offset = Vector2( -141, -49 )
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer"] [node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer"]
margin_top = 13.0 margin_top = 13.0
margin_right = 138.0 margin_right = 89.0
margin_bottom = 27.0 margin_bottom = 27.0
text = "Allow BBCode (Client)" text = "Allow BBCode"
[node name="lucy_bbcode" type="CheckButton" parent="PanelContainer/VBoxContainer/HFlowContainer"] [node name="lucy_bbcode" type="CheckButton" parent="PanelContainer/VBoxContainer/HFlowContainer"]
unique_name_in_owner = true unique_name_in_owner = true
margin_left = 142.0 margin_left = 93.0
margin_right = 218.0 margin_right = 169.0
margin_bottom = 40.0 margin_bottom = 40.0
[node name="Label3" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer"] [node name="Label3" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer"]
margin_left = 222.0 margin_left = 173.0
margin_top = 13.0 margin_top = 13.0
margin_right = 471.0 margin_right = 372.0
margin_bottom = 27.0 margin_bottom = 27.0
text = "Allow Intrusive BBCode (requires Host)" text = "Allow Intrusive BBCode (Client)"
[node name="lucy_intbbcode" type="CheckButton" parent="PanelContainer/VBoxContainer/HFlowContainer"] [node name="lucy_intbbcode" type="CheckButton" parent="PanelContainer/VBoxContainer/HFlowContainer"]
unique_name_in_owner = true unique_name_in_owner = true
margin_left = 475.0 margin_left = 376.0
margin_right = 551.0 margin_right = 452.0
margin_bottom = 40.0 margin_bottom = 40.0
[node name="Label2" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer"] [node name="Label5" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer"]
margin_left = 555.0 margin_left = 456.0
margin_top = 13.0 margin_top = 13.0
margin_right = 690.0 margin_right = 591.0
margin_bottom = 27.0 margin_bottom = 27.0
text = "Punch back on Punch" text = "Punch back on Punch"
[node name="lucy_punchback" type="CheckButton" parent="PanelContainer/VBoxContainer/HFlowContainer"] [node name="lucy_punchback" type="CheckButton" parent="PanelContainer/VBoxContainer/HFlowContainer"]
unique_name_in_owner = true unique_name_in_owner = true
margin_left = 694.0 margin_left = 595.0
margin_right = 770.0 margin_right = 671.0
margin_bottom = 40.0 margin_bottom = 40.0
[node name="HFlowContainer3" type="HFlowContainer" parent="PanelContainer/VBoxContainer"] [node name="HFlowContainer3" type="HFlowContainer" parent="PanelContainer/VBoxContainer"]
margin_top = 70.0
margin_right = 786.0
margin_bottom = 84.0
rect_pivot_offset = Vector2( -141, -49 )
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer3"]
margin_right = 199.0
margin_bottom = 14.0
text = "Host Allows Intrusive BBCode: "
[node name="lucy_srv_allow_bbcode" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer3"]
unique_name_in_owner = true
margin_left = 203.0
margin_right = 221.0
margin_bottom = 14.0
text = "No"
[node name="HSeparator3" type="HSeparator" parent="PanelContainer/VBoxContainer"]
margin_top = 88.0 margin_top = 88.0
margin_right = 786.0 margin_right = 786.0
margin_bottom = 92.0 margin_bottom = 128.0
[node name="Label5" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer3"]
margin_top = 13.0
margin_right = 202.0
margin_bottom = 27.0
text = "Allow Intrusive BBCode (Server)"
[node name="lucy_srv_bbcode" type="CheckButton" parent="PanelContainer/VBoxContainer/HFlowContainer3"]
unique_name_in_owner = true
margin_left = 206.0
margin_right = 282.0
margin_bottom = 40.0
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer3"]
margin_left = 286.0
margin_top = 13.0
margin_right = 397.0
margin_bottom = 27.0
text = "Use Bug BBCode:"
[node name="lucy_bug_bb" type="CheckBox" parent="PanelContainer/VBoxContainer/HFlowContainer3"]
unique_name_in_owner = true
margin_left = 401.0
margin_right = 425.0
margin_bottom = 40.0
[node name="Label2" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer3"]
margin_left = 429.0
margin_top = 13.0
margin_right = 520.0
margin_bottom = 27.0
text = "May be buggy!"
[node name="HSeparator3" type="HSeparator" parent="PanelContainer/VBoxContainer"]
margin_top = 132.0
margin_right = 786.0
margin_bottom = 136.0
[node name="Label2" type="Label" parent="PanelContainer/VBoxContainer"]
margin_top = 140.0
margin_right = 786.0
margin_bottom = 154.0
text = "Custom Server Name - Only shown for LucysTools users (base game field for others)"
[node name="HFlowContainer4" type="HFlowContainer" parent="PanelContainer/VBoxContainer"] [node name="HFlowContainer4" type="HFlowContainer" parent="PanelContainer/VBoxContainer"]
margin_top = 96.0 margin_top = 158.0
margin_right = 786.0 margin_right = 786.0
margin_bottom = 120.0 margin_bottom = 182.0
rect_pivot_offset = Vector2( -141, -49 ) rect_pivot_offset = Vector2( -141, -49 )
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer4"]
margin_top = 5.0
margin_right = 135.0
margin_bottom = 19.0
text = "Custom Server Name"
[node name="lucy_servername" type="LineEdit" parent="PanelContainer/VBoxContainer/HFlowContainer4"] [node name="lucy_servername" type="LineEdit" parent="PanelContainer/VBoxContainer/HFlowContainer4"]
unique_name_in_owner = true unique_name_in_owner = true
margin_left = 139.0
margin_right = 786.0 margin_right = 786.0
margin_bottom = 24.0 margin_bottom = 24.0
size_flags_horizontal = 3 size_flags_horizontal = 3
@@ -117,9 +141,9 @@ expand_to_text_length = true
placeholder_text = "Name" placeholder_text = "Name"
[node name="HFlowContainer6" type="HFlowContainer" parent="PanelContainer/VBoxContainer"] [node name="HFlowContainer6" type="HFlowContainer" parent="PanelContainer/VBoxContainer"]
margin_top = 124.0 margin_top = 186.0
margin_right = 786.0 margin_right = 786.0
margin_bottom = 138.0 margin_bottom = 200.0
rect_pivot_offset = Vector2( -141, -49 ) rect_pivot_offset = Vector2( -141, -49 )
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer6"] [node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer6"]
@@ -139,25 +163,24 @@ text = "'s Lobby"
scroll_active = false scroll_active = false
[node name="HSeparator4" type="HSeparator" parent="PanelContainer/VBoxContainer"] [node name="HSeparator4" type="HSeparator" parent="PanelContainer/VBoxContainer"]
margin_top = 142.0 margin_top = 204.0
margin_right = 786.0 margin_right = 786.0
margin_bottom = 146.0 margin_bottom = 208.0
[node name="Label3" type="Label" parent="PanelContainer/VBoxContainer"]
margin_top = 212.0
margin_right = 786.0
margin_bottom = 226.0
text = "Server Join Message - Will be shown without BBCode for people without LucysTools (without bug enabled)"
[node name="HFlowContainer5" type="HFlowContainer" parent="PanelContainer/VBoxContainer"] [node name="HFlowContainer5" type="HFlowContainer" parent="PanelContainer/VBoxContainer"]
margin_top = 150.0 margin_top = 230.0
margin_right = 786.0 margin_right = 786.0
margin_bottom = 174.0 margin_bottom = 254.0
rect_pivot_offset = Vector2( -141, -49 ) rect_pivot_offset = Vector2( -141, -49 )
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer5"]
margin_top = 5.0
margin_right = 127.0
margin_bottom = 19.0
text = "Server Join Message"
[node name="lucy_servermsg" type="LineEdit" parent="PanelContainer/VBoxContainer/HFlowContainer5"] [node name="lucy_servermsg" type="LineEdit" parent="PanelContainer/VBoxContainer/HFlowContainer5"]
unique_name_in_owner = true unique_name_in_owner = true
margin_left = 131.0
margin_right = 786.0 margin_right = 786.0
margin_bottom = 24.0 margin_bottom = 24.0
size_flags_horizontal = 3 size_flags_horizontal = 3
@@ -165,19 +188,39 @@ expand_to_text_length = true
placeholder_text = "Message" placeholder_text = "Message"
[node name="HFlowContainer7" type="HFlowContainer" parent="PanelContainer/VBoxContainer"] [node name="HFlowContainer7" type="HFlowContainer" parent="PanelContainer/VBoxContainer"]
margin_top = 178.0 margin_top = 258.0
margin_right = 786.0 margin_right = 786.0
margin_bottom = 192.0 margin_bottom = 272.0
rect_pivot_offset = Vector2( -141, -49 ) rect_pivot_offset = Vector2( -141, -49 )
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer7"] [node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer7"]
margin_right = 145.0 margin_right = 109.0
margin_bottom = 14.0 margin_bottom = 14.0
text = "Join Message Preview: " text = "Normal Preview: "
[node name="lucy_servermsg_preview" type="RichTextLabel" parent="PanelContainer/VBoxContainer/HFlowContainer7"] [node name="lucy_servermsg_preview" type="RichTextLabel" parent="PanelContainer/VBoxContainer/HFlowContainer7"]
unique_name_in_owner = true unique_name_in_owner = true
margin_left = 149.0 margin_left = 113.0
margin_right = 786.0
margin_bottom = 14.0
size_flags_horizontal = 3
bbcode_enabled = true
scroll_active = false
[node name="HFlowContainer10" type="HFlowContainer" parent="PanelContainer/VBoxContainer"]
margin_top = 276.0
margin_right = 786.0
margin_bottom = 290.0
rect_pivot_offset = Vector2( -141, -49 )
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer10"]
margin_right = 97.0
margin_bottom = 14.0
text = "Lame Preview: "
[node name="lucy_servermsg_preview2" type="RichTextLabel" parent="PanelContainer/VBoxContainer/HFlowContainer10"]
unique_name_in_owner = true
margin_left = 101.0
margin_right = 786.0 margin_right = 786.0
margin_bottom = 14.0 margin_bottom = 14.0
size_flags_horizontal = 3 size_flags_horizontal = 3
@@ -185,82 +228,111 @@ bbcode_enabled = true
scroll_active = false scroll_active = false
[node name="HSeparator5" type="HSeparator" parent="PanelContainer/VBoxContainer"] [node name="HSeparator5" type="HSeparator" parent="PanelContainer/VBoxContainer"]
margin_top = 196.0 margin_top = 294.0
margin_right = 786.0 margin_right = 786.0
margin_bottom = 200.0 margin_bottom = 298.0
[node name="HFlowContainer8" type="HFlowContainer" parent="PanelContainer/VBoxContainer"] [node name="HFlowContainer8" type="HFlowContainer" parent="PanelContainer/VBoxContainer"]
margin_top = 204.0 margin_top = 302.0
margin_right = 786.0 margin_right = 786.0
margin_bottom = 228.0 margin_bottom = 326.0
rect_pivot_offset = Vector2( -141, -49 ) rect_pivot_offset = Vector2( -141, -49 )
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer8"] [node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer8"]
margin_top = 5.0 margin_top = 5.0
margin_right = 107.0 margin_right = 157.0
margin_bottom = 19.0 margin_bottom = 19.0
text = "Chat Name Color" text = "Chat Name Color (global)"
[node name="lucy_chatcolor_bool" type="CheckBox" parent="PanelContainer/VBoxContainer/HFlowContainer8"] [node name="lucy_chatcolor_bool" type="CheckBox" parent="PanelContainer/VBoxContainer/HFlowContainer8"]
unique_name_in_owner = true unique_name_in_owner = true
margin_left = 111.0 margin_left = 161.0
margin_right = 181.0 margin_right = 231.0
margin_bottom = 24.0 margin_bottom = 24.0
text = "Enable" text = "Enable"
[node name="lucy_chatcolor" type="ColorPickerButton" parent="PanelContainer/VBoxContainer/HFlowContainer8"] [node name="lucy_chatcolor" type="ColorPickerButton" parent="PanelContainer/VBoxContainer/HFlowContainer8"]
unique_name_in_owner = true unique_name_in_owner = true
margin_left = 185.0 margin_left = 235.0
margin_right = 227.0 margin_right = 277.0
margin_bottom = 24.0
rect_min_size = Vector2( 42, 0 )
edit_alpha = false
[node name="Label2" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer8"]
margin_left = 281.0
margin_top = 5.0
margin_right = 519.0
margin_bottom = 19.0
text = " Chat Text Color (LucysTools or bug)"
[node name="lucy_chatcolor_bool2" type="CheckBox" parent="PanelContainer/VBoxContainer/HFlowContainer8"]
unique_name_in_owner = true
margin_left = 523.0
margin_right = 593.0
margin_bottom = 24.0
text = "Enable"
[node name="lucy_chatcolor2" type="ColorPickerButton" parent="PanelContainer/VBoxContainer/HFlowContainer8"]
unique_name_in_owner = true
margin_left = 597.0
margin_right = 639.0
margin_bottom = 24.0 margin_bottom = 24.0
rect_min_size = Vector2( 42, 0 ) rect_min_size = Vector2( 42, 0 )
edit_alpha = false edit_alpha = false
[node name="HFlowContainer9" type="HFlowContainer" parent="PanelContainer/VBoxContainer"] [node name="HFlowContainer9" type="HFlowContainer" parent="PanelContainer/VBoxContainer"]
margin_top = 232.0 margin_top = 330.0
margin_right = 786.0 margin_right = 786.0
margin_bottom = 256.0 margin_bottom = 344.0
rect_pivot_offset = Vector2( -141, -49 ) rect_pivot_offset = Vector2( -141, -49 )
hint_tooltip = "Must match Steam username" hint_tooltip = "Must match Steam username"
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer9"] [node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer9"]
margin_top = 5.0 margin_right = 392.0
margin_right = 91.0 margin_bottom = 14.0
margin_bottom = 19.0 text = "Custom Name - Must match Steam Name (LucysTools or bug)"
text = "Custom Name"
[node name="lucy_namegood" type="RichTextLabel" parent="PanelContainer/VBoxContainer/HFlowContainer9"] [node name="lucy_namegood" type="RichTextLabel" parent="PanelContainer/VBoxContainer/HFlowContainer9"]
unique_name_in_owner = true unique_name_in_owner = true
margin_left = 95.0 margin_left = 396.0
margin_right = 145.0 margin_right = 446.0
margin_bottom = 24.0 margin_bottom = 14.0
rect_min_size = Vector2( 50, 0 ) rect_min_size = Vector2( 50, 0 )
bbcode_enabled = true bbcode_enabled = true
bbcode_text = "[color=green]Good[/color]" bbcode_text = "[color=green]Good[/color]"
text = "Good" text = "Good"
scroll_active = false scroll_active = false
[node name="lucy_name" type="LineEdit" parent="PanelContainer/VBoxContainer/HFlowContainer9"] [node name="lucy_name" type="LineEdit" parent="PanelContainer/VBoxContainer"]
unique_name_in_owner = true unique_name_in_owner = true
margin_left = 149.0 margin_top = 348.0
margin_right = 207.0 margin_right = 786.0
margin_bottom = 24.0 margin_bottom = 372.0
expand_to_text_length = true expand_to_text_length = true
placeholder_text = "Name" placeholder_text = "Name"
[node name="lucy_name_preview" type="RichTextLabel" parent="PanelContainer/VBoxContainer/HFlowContainer9"] [node name="lucy_name_preview" type="RichTextLabel" parent="PanelContainer/VBoxContainer"]
unique_name_in_owner = true unique_name_in_owner = true
margin_left = 211.0 margin_top = 376.0
margin_right = 786.0 margin_right = 786.0
margin_bottom = 24.0 margin_bottom = 391.0
rect_min_size = Vector2( 0, 15 )
size_flags_horizontal = 3 size_flags_horizontal = 3
bbcode_enabled = true bbcode_enabled = true
bbcode_text = "If you see this, modify your custom name"
text = "If you see this, modify your custom name"
scroll_active = false scroll_active = false
[node name="HFlowContainer2" type="HFlowContainer" parent="PanelContainer/VBoxContainer"] [node name="HSeparator6" type="HSeparator" parent="PanelContainer/VBoxContainer"]
margin_top = 260.0 margin_top = 395.0
margin_right = 786.0 margin_right = 786.0
margin_bottom = 280.0 margin_bottom = 399.0
[node name="HFlowContainer2" type="HFlowContainer" parent="PanelContainer/VBoxContainer"]
margin_top = 403.0
margin_right = 786.0
margin_bottom = 423.0
[node name="lucy_clearchat" type="Button" parent="PanelContainer/VBoxContainer/HFlowContainer2"] [node name="lucy_clearchat" type="Button" parent="PanelContainer/VBoxContainer/HFlowContainer2"]
margin_right = 76.0 margin_right = 76.0
@@ -303,120 +375,21 @@ margin_right = 571.0
margin_bottom = 20.0 margin_bottom = 20.0
text = "Clear Meteor" text = "Clear Meteor"
[node name="HSeparator2" type="HSeparator" parent="PanelContainer/VBoxContainer"]
margin_top = 284.0
margin_right = 786.0
margin_bottom = 288.0
[node name="HSplitContainer" type="HSplitContainer" parent="PanelContainer/VBoxContainer"]
margin_top = 292.0
margin_right = 786.0
margin_bottom = 316.0
split_offset = 100
[node name="HFlowContainer3" type="HFlowContainer" parent="PanelContainer/VBoxContainer/HSplitContainer"]
margin_right = 218.0
margin_bottom = 24.0
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HSplitContainer/HFlowContainer3"]
margin_top = 5.0
margin_right = 118.0
margin_bottom = 19.0
text = "Per Frame Packets"
[node name="lucy_fpackets" type="SpinBox" parent="PanelContainer/VBoxContainer/HSplitContainer/HFlowContainer3"]
unique_name_in_owner = true
margin_left = 122.0
margin_right = 196.0
margin_bottom = 24.0
max_value = 256.0
value = 32.0
rounded = true
allow_greater = true
[node name="HFlowContainer" type="HFlowContainer" parent="PanelContainer/VBoxContainer/HSplitContainer"]
margin_left = 230.0
margin_right = 786.0
margin_bottom = 24.0
[node name="Label2" type="Label" parent="PanelContainer/VBoxContainer/HSplitContainer/HFlowContainer"]
margin_top = 5.0
margin_right = 116.0
margin_bottom = 19.0
text = "Bulk Read Packets"
[node name="lucy_bpackets" type="SpinBox" parent="PanelContainer/VBoxContainer/HSplitContainer/HFlowContainer"]
unique_name_in_owner = true
margin_left = 120.0
margin_right = 194.0
margin_bottom = 24.0
max_value = 4096.0
value = 128.0
rounded = true
allow_greater = true
[node name="HSplitContainer2" type="HSplitContainer" parent="PanelContainer/VBoxContainer"]
margin_top = 320.0
margin_right = 786.0
margin_bottom = 344.0
split_offset = 100
[node name="HFlowContainer3" type="HFlowContainer" parent="PanelContainer/VBoxContainer/HSplitContainer2"]
margin_right = 216.0
margin_bottom = 24.0
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HSplitContainer2/HFlowContainer3"]
margin_top = 5.0
margin_right = 116.0
margin_bottom = 19.0
text = "Bulk Read Interval"
[node name="lucy_binterval" type="SpinBox" parent="PanelContainer/VBoxContainer/HSplitContainer2/HFlowContainer3"]
unique_name_in_owner = true
margin_left = 120.0
margin_right = 194.0
margin_bottom = 24.0
max_value = 120.0
step = 0.05
value = 0.8
allow_greater = true
[node name="HFlowContainer" type="HFlowContainer" parent="PanelContainer/VBoxContainer/HSplitContainer2"]
margin_left = 228.0
margin_right = 786.0
margin_bottom = 24.0
[node name="Label2" type="Label" parent="PanelContainer/VBoxContainer/HSplitContainer2/HFlowContainer"]
margin_top = 5.0
margin_right = 111.0
margin_bottom = 19.0
text = "Full Read Interval"
[node name="lucy_finterval" type="SpinBox" parent="PanelContainer/VBoxContainer/HSplitContainer2/HFlowContainer"]
unique_name_in_owner = true
margin_left = 115.0
margin_right = 189.0
margin_bottom = 24.0
max_value = 120.0
step = 0.05
value = 6.4
allow_greater = true
[connection signal="toggled" from="PanelContainer/VBoxContainer/HFlowContainer/lucy_bbcode" to="." method="_on_lucy_bbcode_toggled"] [connection signal="toggled" from="PanelContainer/VBoxContainer/HFlowContainer/lucy_bbcode" to="." method="_on_lucy_bbcode_toggled"]
[connection signal="toggled" from="PanelContainer/VBoxContainer/HFlowContainer/lucy_intbbcode" to="." method="_on_lucy_intbbcode_toggled"] [connection signal="toggled" from="PanelContainer/VBoxContainer/HFlowContainer/lucy_intbbcode" to="." method="_on_lucy_intbbcode_toggled"]
[connection signal="toggled" from="PanelContainer/VBoxContainer/HFlowContainer/lucy_punchback" to="." method="_on_lucy_punchback_toggled"] [connection signal="toggled" from="PanelContainer/VBoxContainer/HFlowContainer/lucy_punchback" to="." method="_on_lucy_punchback_toggled"]
[connection signal="toggled" from="PanelContainer/VBoxContainer/HFlowContainer3/lucy_srv_bbcode" to="." method="_on_lucy_srv_bbcode_toggled"]
[connection signal="toggled" from="PanelContainer/VBoxContainer/HFlowContainer3/lucy_bug_bb" to="." method="_on_lucy_bug_bb_toggled"]
[connection signal="text_changed" from="PanelContainer/VBoxContainer/HFlowContainer4/lucy_servername" to="." method="_on_lucy_servername_text_changed"] [connection signal="text_changed" from="PanelContainer/VBoxContainer/HFlowContainer4/lucy_servername" to="." method="_on_lucy_servername_text_changed"]
[connection signal="text_changed" from="PanelContainer/VBoxContainer/HFlowContainer5/lucy_servermsg" to="." method="_on_lucy_servermsg_text_changed"] [connection signal="text_changed" from="PanelContainer/VBoxContainer/HFlowContainer5/lucy_servermsg" to="." method="_on_lucy_servermsg_text_changed"]
[connection signal="toggled" from="PanelContainer/VBoxContainer/HFlowContainer8/lucy_chatcolor_bool" to="." method="_on_lucy_chatcolor_bool_toggled"] [connection signal="toggled" from="PanelContainer/VBoxContainer/HFlowContainer8/lucy_chatcolor_bool" to="." method="_on_lucy_chatcolor_bool_toggled"]
[connection signal="color_changed" from="PanelContainer/VBoxContainer/HFlowContainer8/lucy_chatcolor" to="." method="_on_lucy_chatcolor_color_changed"] [connection signal="color_changed" from="PanelContainer/VBoxContainer/HFlowContainer8/lucy_chatcolor" to="." method="_on_lucy_chatcolor_color_changed"]
[connection signal="text_changed" from="PanelContainer/VBoxContainer/HFlowContainer9/lucy_name" to="." method="_on_lucy_name_text_changed"] [connection signal="toggled" from="PanelContainer/VBoxContainer/HFlowContainer8/lucy_chatcolor_bool2" to="." method="_on_lucy_chatcolor_bool2_toggled"]
[connection signal="color_changed" from="PanelContainer/VBoxContainer/HFlowContainer8/lucy_chatcolor2" to="." method="_on_lucy_chatcolor2_color_changed"]
[connection signal="text_changed" from="PanelContainer/VBoxContainer/lucy_name" to="." method="_on_lucy_name_text_changed"]
[connection signal="pressed" from="PanelContainer/VBoxContainer/HFlowContainer2/lucy_clearchat" to="." method="_on_lucy_clearchat_pressed"] [connection signal="pressed" from="PanelContainer/VBoxContainer/HFlowContainer2/lucy_clearchat" to="." method="_on_lucy_clearchat_pressed"]
[connection signal="pressed" from="PanelContainer/VBoxContainer/HFlowContainer2/lucy_raincloud" to="." method="_on_lucy_raincloud_pressed"] [connection signal="pressed" from="PanelContainer/VBoxContainer/HFlowContainer2/lucy_raincloud" to="." method="_on_lucy_raincloud_pressed"]
[connection signal="pressed" from="PanelContainer/VBoxContainer/HFlowContainer2/lucy_meteor" to="." method="_on_lucy_meteor_pressed"] [connection signal="pressed" from="PanelContainer/VBoxContainer/HFlowContainer2/lucy_meteor" to="." method="_on_lucy_meteor_pressed"]
[connection signal="pressed" from="PanelContainer/VBoxContainer/HFlowContainer2/lucy_freezerain" to="." method="_on_lucy_freezerain_pressed"] [connection signal="pressed" from="PanelContainer/VBoxContainer/HFlowContainer2/lucy_freezerain" to="." method="_on_lucy_freezerain_pressed"]
[connection signal="pressed" from="PanelContainer/VBoxContainer/HFlowContainer2/lucy_clearrain" to="." method="_on_lucy_clearrain_pressed"] [connection signal="pressed" from="PanelContainer/VBoxContainer/HFlowContainer2/lucy_clearrain" to="." method="_on_lucy_clearrain_pressed"]
[connection signal="pressed" from="PanelContainer/VBoxContainer/HFlowContainer2/lucy_clearmeteor" to="." method="_on_lucy_clearmeteor_pressed"] [connection signal="pressed" from="PanelContainer/VBoxContainer/HFlowContainer2/lucy_clearmeteor" to="." method="_on_lucy_clearmeteor_pressed"]
[connection signal="value_changed" from="PanelContainer/VBoxContainer/HSplitContainer/HFlowContainer3/lucy_fpackets" to="." method="_on_lucy_fpackets_value_changed"]
[connection signal="value_changed" from="PanelContainer/VBoxContainer/HSplitContainer/HFlowContainer/lucy_bpackets" to="." method="_on_lucy_bpackets_value_changed"]
[connection signal="value_changed" from="PanelContainer/VBoxContainer/HSplitContainer2/HFlowContainer3/lucy_binterval" to="." method="_on_lucy_binterval_value_changed"]
[connection signal="value_changed" from="PanelContainer/VBoxContainer/HSplitContainer2/HFlowContainer/lucy_finterval" to="." method="_on_lucy_finterval_value_changed"]

View File

@@ -5,110 +5,446 @@ const LUCYS_MENU_SCENE = preload("res://mods/Lucy.LucysTools/lucys_menu.tscn")
var lucys_menu = null var lucys_menu = null
onready var root = get_tree().root onready var root = get_tree().root
var do_punchback = false var INCERCEPT_MSG: bool = false
var allow_bbcode = false var INCERCEPT_SEND_MSG: bool = false
var custom_server_name = "" setget set_server_name
var server_join_message = "[color=#5BCEFA]TRAN[/color][color=#F5A9B8]S RIG[/color][color=#ffffff]HTS![/color]" setget set_join_message
var frame_packets = 50 setget set_frame_packets
var bulk_packets = 200 setget set_bulk_packets
var bulk_interval = 1 setget set_bulk_interval
var full_interval = 5 setget set_full_interval
var custom_color_enabled = false var do_punchback: bool = false
var custom_color = Color("009cd0") setget set_custom_color var allow_bbcode: bool = false
var custom_server_name: String = "" setget set_server_name
var server_join_message: String = "[color=#5BCEFA]TRAN[/color][color=#F5A9B8]S RIG[/color][color=#ffffff]HTS![/color]" setget set_join_message
var custom_name_enabled = false var custom_color_enabled: bool = false
var custom_name = "" var custom_color: Color = Color("009cd0") setget set_custom_color
var allow_intrusive_bbcode = false setget set_allow_intrusive_bbcode var custom_name_enabled: bool = false
var srv_allow_bbcode = false setget set_srv_bbcode var real_custom_name: String = ""
var custom_name: String = "" setget set_custom_name
var log_messages = false setget set_log_messages var allow_intrusive_bbcode: bool = false setget set_allow_intrusive_bbcode
var srv_bbcode: bool = false setget set_srv_bbcode
var log_messages: bool = false setget set_log_messages
var allowed_tags = ["b", "i", "u", "s", "color"] var DEBUG: bool = false
var escape_invalid = true
var lucys_menu_visible: bool = true
var custom_text_color: Color = Color("00ff00")
var custom_text_color_enabled: bool = false
var bug_bbcode: bool = false
func set_custom_name(val):
custom_name = val
var bb = bbcode_process(val, 256)
real_custom_name = bb.fin
func set_log_messages(val):
log_messages = val
Network.LUCY_LOG_MESSAGES = val
func set_allow_intrusive_bbcode(bbcode):
allow_intrusive_bbcode = bbcode
bbcode_changes()
func set_srv_bbcode(bbcode):
srv_bbcode = bbcode
if Network.GAME_MASTER: send_lucy_sync()
bbcode_changes()
func set_server_name(name):
custom_server_name = name
Network.LUCY_SRV_NAME = name
func set_join_message(msg):
server_join_message = msg
func set_custom_color(val):
custom_color = Color(val) if Color(val) != Color("d5aa73") else Color("739ed5")
custom_color.a = 1
var allowed_tags: Array = ["b", "i", "u", "s", "color"]
var escape_invalid: bool = true
var strip_disallowed: bool = true
var check_alpha: bool = true setget set_check_alpha
var bbcode_matcher = null var bbcode_matcher = null
# i know this sucks var junk_checkers: Dictionary = {}
# but i have things to do
func bbcode_recurse(text, data): var alpha_lim := 0.5
var m = bbcode_matcher.search(text)
if m == null: var alpha_getter: RegEx = null
var escaped = text.replace('[lb]','[').replace('[','[lb]') if escape_invalid else text func do_alpha_check(junk) -> String:
data.fin += escaped if not alpha_getter:
data.stripped += escaped alpha_getter = RegEx.new()
else: alpha_getter.compile("\\s*=\\s*(\\S*)")
#print("Found ", m.strings, " in '", text, "'")
bbcode_recurse(m.get_string(1), data) var color: Color = Color(alpha_getter.search(junk).get_string(1))
var tag = m.get_string(2)
var junk = m.get_string(3) if color.a < alpha_lim:
var allowed = tag in allowed_tags color.a = alpha_lim
if allowed: return "=#" + color.to_html()
data.fin += "[" + tag + junk + "]"
else: return ""
data.fin += "[lb]" + tag + junk + "]"
data.stripped += "[lb]" + tag + junk + "]" func set_check_alpha(val):
#print("TAG ", m.get_string(2), " JUNK ", m.get_string(3)) check_alpha = val
data.tags.append([tag, junk]) if val: junk_checkers["color"] = funcref(self, "do_alpha_check")
bbcode_recurse(m.get_string(4), data) else: junk_checkers.erase("color")
if allowed:
data.fin += "[/" + tag + "]" var INNER_MAX_LEN: int = 0
else:
data.fin += "[lb]/" + tag + "]" # ouch oof this sucks
data.stripped += "[lb]/" + tag + "]" func bbcode_process(text, max_len) -> Dictionary:
bbcode_recurse(m.get_string(5), data) var end: int
var all: String
var before: String
var whole_tag: String
var tag_open: String
var junk: String
var tag_close: String
var tag: String
var is_close: bool
var inner_full: String
var inner_stripped: String
var prev_full: String
var prev_stripped: String
var checked: String
var last_tag
if DEBUG:
var thing = {"max_len":max_len,"allowed_tags":allowed_tags,"strip_disallowed":strip_disallowed,"escape_invalid":escape_invalid}
print("[BBCODE NEW] processing '", text, "' params ", thing)
func bbcode_process(text):
bbcode_matcher = RegEx.new() bbcode_matcher = RegEx.new()
bbcode_matcher.compile("^(.*?)\\[(\\w+?)([^\\]]*)\\](.+?)\\[/\\2\\](.*?)$") bbcode_matcher.compile("(.*?)(\\[(\\w+)([^\\[\\]]*?)\\]|\\[/(\\w+)\\])")
#print("processing '", text, "'")
var data = {"fin": "", "tags": [], "stripped": ""}
bbcode_recurse(text, data)
return data
# Patched Network vars var linear_matches: Array = bbcode_matcher.search_all(text)
# var LUCY_PACKETS_READ = 0 if linear_matches.empty():
# var LUCY_BULK_FULL_TIMER = 0 var processed = {"fin": text.replace('[','[lb]'), "stripped": text}
# var LUCY_FRAME_PACKETS = 32 if DEBUG: print("[BBCODE NEW] processed ", processed)
# var LUCY_BULK_PACKETS = 128 return processed
# var LUCY_BULK_INTERVAL = 0.8
# var LUCY_BULK_FULL_INTERVAL = 6.4 var tag_stack := []
# var LUCY_SRV_NAME var full_text_stack := [""]
# var LUCY_PUNCHED_ME var stripped_text_stack := [""]
# var LUCY_INSTANCE_SENDER
# var LUCY_LOG_MESSAGES var last_end: int = 0
# all this popping and pushing sucks. whatever
for m in linear_matches:
if DEBUG: print("[MATCH] ", m.strings)
if DEBUG: print("[STACKS] ", {
"tag stack": tag_stack,
"full text": full_text_stack,
"stripped text": stripped_text_stack
})
end = m.get_end()
if end != -1: last_end = end
all = m.get_string(0)
before = m.get_string(1)
whole_tag = m.get_string(2)
tag_open = m.get_string(3)
junk = m.get_string(4)
tag_close = m.get_string(5)
tag = tag_open
is_close = false
if tag_open == "":
tag = tag_close
is_close = true
if is_close:
# get the tag on the stack
last_tag = tag_stack.pop_back()
# get the full text on the stack
inner_full = full_text_stack.pop_back()
# get the stripped text on the stack
inner_stripped = stripped_text_stack.pop_back()
if last_tag == null:
if DEBUG: print("[UNOPENED CLOSE]")
# no tags on stack
# add stripped tag to all text
# and go back on stack
full_text_stack.push_back(inner_full+before.replace('[','[lb]')+"[lb]/"+tag+"]")
stripped_text_stack.push_back(inner_stripped+before.replace('[','[lb]')+"[lb]/"+tag+"]")
continue
elif last_tag[0] == tag:
if DEBUG: print("[CLOSED TAG]")
# we have closure.
# check junk
if junk_checkers.has(tag):
checked = junk_checkers[tag].call_func(last_tag[1])
junk = last_tag[1] if checked == "" else checked
if DEBUG: print("[BB NEW JUNK] ", junk)
else:
junk = last_tag[1]
# add tag in full text
# but not in stripped
prev_full = full_text_stack.pop_back()
prev_stripped = stripped_text_stack.pop_back()
if tag in allowed_tags:
full_text_stack.push_back(prev_full + "["+tag+junk+"]" + inner_full + before.replace('[','[lb]') + "[/"+tag+"]")
stripped_text_stack.push_back(prev_stripped + inner_stripped + before.replace('[','[lb]'))
else:
full_text_stack.push_back(prev_full + inner_full + before.replace('[','[lb]'))
stripped_text_stack.push_back(prev_stripped + inner_stripped + before.replace('[','[lb]'))
continue
else:
if DEBUG: print("[WRONG CLOSE]")
# open followed by different close
# escape and add the text to previous on stack
prev_full = full_text_stack.pop_back()
prev_stripped = stripped_text_stack.pop_back()
full_text_stack.push_back(prev_full + "[lb]"+last_tag[0]+last_tag[1]+"]" + inner_full + before.replace('[','[lb]') + "[lb]/"+tag+"]")
stripped_text_stack.push_back(prev_stripped + "[lb]"+last_tag[0]+last_tag[1]+"]" + inner_stripped + before.replace('[','[lb]') + "[lb]/"+tag+"]")
continue
else:
# special case
if tag == "lb" or tag == "rb":
if DEBUG: print("[LB/RB]")
# add directly to current inner
inner_full = full_text_stack.pop_back()
inner_stripped = stripped_text_stack.pop_back()
full_text_stack.push_back(inner_full + before.replace('[','[lb]') + whole_tag)
stripped_text_stack.push_back(inner_stripped + before.replace('[','[lb]') + whole_tag)
continue
if DEBUG: print("[OPEN TAG]")
# add to stack
tag_stack.push_back([tag, junk])
# add before text escaped to prev
inner_full = full_text_stack.pop_back()
inner_stripped = stripped_text_stack.pop_back()
full_text_stack.push_back(inner_full + before.replace('[','[lb]'))
stripped_text_stack.push_back(inner_stripped + before.replace('[','[lb]'))
# new inner text
full_text_stack.push_back("")
stripped_text_stack.push_back("")
continue
if DEBUG: print("[FINAL STACKS] ", {
"tag stack": tag_stack,
"full text": full_text_stack,
"stripped text": stripped_text_stack
})
# unroll opens at end
# TODO probably should write this in as escaped
# but im getting tired
while not tag_stack.empty():
tag_stack.pop_back()
full_text_stack.pop_back()
stripped_text_stack.pop_back()
if DEBUG: print("[LAST END] ", last_end)
var processed = {"fin": full_text_stack.pop_back(), "stripped": stripped_text_stack.pop_back()}
# end stuff isnt caught by the regex
if last_end != 0:
var end_str = text.substr(last_end).replace('[','[lb]')
if DEBUG: print("[END STR] ", end_str)
processed.fin += end_str
processed.stripped += end_str
if DEBUG: print("[BBCODE NEW] processed ", processed)
return processed
var ingame = false var ingame = false
func process_message(lit_text, final_text, prefix, suffix, endcap, username, final_color, spoken_text): func get_user_color() -> Color:
var base_color = Color(Globals.cosmetic_data[PlayerData.cosmetics_equipped["primary_color"]]["file"].main_color) * Color(0.95, 0.9, 0.9)
var color = custom_color if custom_color_enabled else base_color
return color
func safe_message(user_id, color, boring_msg, local, lucy_user, lucy_msg, require_name):
var msg: String = boring_msg
if lucy_msg != "": msg = lucy_msg
var net_name: String = Network._get_username_from_id(user_id).replace('[','').replace(']','')
var name: String = net_name if lucy_user == "" else lucy_user
if OptionsMenu.chat_filter:
msg = SwearFilter._filter_string(msg)
msg = msg.replace("%u", "[color=#" + str(color) + "]" + name + "[/color]")
if DEBUG: print("[MSG B4 PROC] ", msg)
# process message
var bb_msg = bbcode_process(msg, 512)
if require_name and not net_name in bb_msg.stripped:
msg = net_name + ": " + msg
bb_msg = bbcode_process(msg, 512)
if log_messages:
var thing = {"user_id":user_id, "steam name":Network._get_username_from_id(user_id),
"username":name, "color":color,
"final": bb_msg.fin, "message": boring_msg,
"bb_user":lucy_user,"bb_msg":lucy_msg}
print("[MESSAGE] ", thing)
Network._update_chat(bb_msg.fin, local)
# this is stinky
func process_message(lit_text, final, prefix, suffix, endcap, spoken_text, local, colon, playerhud):
if log_messages:
var thing = { var thing = {
"lit_text": lit_text, "final_text": final_text, "prefix": prefix, "suffix": suffix, "lit_text": lit_text, "final": final, "prefix": prefix, "suffix": suffix,
"endcap": endcap, "username": username, "final_color": final_color, "endcap": endcap,
"srv_allow_bbcode": srv_allow_bbcode, "custom_color_enabled": custom_color_enabled, "custom_color_enabled": custom_color_enabled,
"custom_name_enabled": custom_name_enabled, "allow_bbcode": allow_bbcode, "custom_name_enabled": custom_name_enabled, "allow_bbcode": allow_bbcode,
"allowed_tags": allowed_tags "allowed_tags": allowed_tags
} }
#print("FUCK ", thing) print("process_message ", thing)
if srv_allow_bbcode and lit_text.begins_with("%"):
return [lit_text.trim_prefix('%'), spoken_text]
var name = custom_name if custom_name_enabled else username if (Network.GAME_MASTER or Network.PLAYING_OFFLINE) and lit_text.begins_with("%"):
var color = custom_color if custom_color_enabled else final_color var bb_dat = bbcode_process(lit_text.trim_prefix('%'), 512)
var msg = final_text
if bug_bbcode:
print("Using color field...")
var evil_color = "00ff0000]"\
+ "[color=#ffeed5]"\
+ bb_dat.fin\
+ "[/color]"
if bb_dat.fin != "":
lucy_send_message("", "%u", false, evil_color)
return [true]
lucy_send_message(lit_text.trim_prefix('%'), bb_dat.stripped, false)
# we sent the message ourself
return [true]
var msg = final
var boring_msg = final
var speak = spoken_text var speak = spoken_text
if allow_bbcode: if bug_bbcode:
var p = bbcode_process(lit_text) print("Using color field...")
if not p.tags.empty(): var p = bbcode_process(lit_text, 512)
msg = p.fin var name = real_custom_name if custom_name_enabled else Network.STEAM_USERNAME
var name_color = get_user_color().to_html()
var text_color = "ffffeed5" if not custom_text_color_enabled else custom_text_color.to_html()
var evil_color = "00ff0000]"\
+ "[color=#" + text_color + "]"\
+ prefix\
+ "[color=#" + name_color + "]"\
+ name\
+ "[/color]"\
+ endcap + p.fin + suffix\
+ "[/color]"
boring_msg = "%u"
var bb_msg = ""
var bb_user = ""
speak = p.stripped speak = p.stripped
return [
prefix + "[color=#" + str(color.to_html()) + "]" + name + endcap + msg + suffix, if p.fin != "":
speak lucy_send_message(bb_msg, boring_msg, local, evil_color)
]
if speak != "" and colon: playerhud.emit_signal("_message_sent", speak)
return [true]
elif allow_bbcode:
var p = bbcode_process(lit_text, 512)
var txt_col_start = "" if not custom_text_color_enabled else\
"[color=#"+custom_text_color.to_html()+"]"
var txt_col_end = "" if not custom_text_color_enabled else\
"[/color]"
msg = prefix + "%u" + txt_col_start + endcap + p.fin + suffix + txt_col_end
boring_msg = prefix + "%u" + endcap + p.stripped + suffix
speak = p.stripped
if msg != "": lucy_send_message(msg, boring_msg, local)
if speak != "" and colon: playerhud.emit_signal("_message_sent", speak)
# we did it ourselves
return [true]
# return the custom color
return [false, get_user_color().to_html()]
var LUCYSTOOLS_USERS = []
func lucy_send_message(message, boring_msg, local = false, evil_color = ""):
if not Network._message_cap(Network.STEAM_ID):
Network._update_chat("Sending too many messages too quickly!", false)
Network._update_chat("Sending too many messages too quickly!", true)
return
var msg_pos = Network.MESSAGE_ORIGIN.round()
var lucy_user = real_custom_name if custom_name_enabled and not bug_bbcode else ""
var color = get_user_color().to_html() if not bug_bbcode else evil_color
safe_message(Network.STEAM_ID, color, boring_msg, local, lucy_user, message, false)
Network._send_P2P_Packet(
{"type": "message", "message": boring_msg, "color": color, "local": local,
"position": Network.MESSAGE_ORIGIN, "zone": Network.MESSAGE_ZONE,
"zone_owner": PlayerData.player_saved_zone_owner,
"bb_user": lucy_user, "bb_msg": message},
"peers", 2, Network.CHANNELS.GAME_STATE)
func process_read(DATA, PACKET_SENDER, from_host) -> bool:
match DATA["type"]:
"lucy_packet":
print("[LUCY PACKET]")
if not PACKET_SENDER in LUCYSTOOLS_USERS: LUCYSTOOLS_USERS.append(PACKET_SENDER)
if Network.GAME_MASTER or not from_host: return true
if not Network._validate_packet_information(DATA, ["srv_bbcode"], [TYPE_BOOL]): return true
self.srv_bbcode = DATA["srv_bbcode"]
return true
"message":
var has_bb = true
if not Network._validate_packet_information(DATA,
["message", "color", "local", "position", "zone", "zone_owner", "bb_user", "bb_msg"],
[TYPE_STRING, TYPE_STRING, TYPE_BOOL, TYPE_VECTOR3, TYPE_STRING, TYPE_INT, TYPE_STRING, TYPE_STRING]):
has_bb = false
if not Network._validate_packet_information(DATA,
["message", "color", "local", "position", "zone", "zone_owner"],
[TYPE_STRING, TYPE_STRING, TYPE_BOOL, TYPE_VECTOR3, TYPE_STRING, TYPE_INT]):
# invalid packet
if log_messages:
print("[MALFORMED MESSAGE] sender: ", Network._get_username_from_id(PACKET_SENDER), "(", PACKET_SENDER + ") " + DATA)
return true
if has_bb:
if not PACKET_SENDER in LUCYSTOOLS_USERS:
LUCYSTOOLS_USERS.append(PACKET_SENDER)
if PlayerData.players_muted.has(PACKET_SENDER) or PlayerData.players_hidden.has(PACKET_SENDER):
return false
if not Network._message_cap(PACKET_SENDER): return false
var user_id: int = PACKET_SENDER
var user_color: String = DATA["color"]
var user_message: String = DATA["message"]
# if host, don't care about visibility
check_alpha = not from_host
var bb_user: String = ""
var bb_msg: String = ""
if has_bb:
bb_user = DATA["bb_user"]
bb_msg = DATA["bb_msg"]
if not DATA["local"]:
safe_message(user_id, user_color, user_message, false, bb_user, bb_msg, not from_host)
else :
var dist = DATA["position"].distance_to(Network.MESSAGE_ORIGIN)
if DATA["zone"] == Network.MESSAGE_ZONE and DATA["zone_owner"] == PlayerData.player_saved_zone_owner:
if dist < 25.0: safe_message(user_id, user_color, user_message, true, bb_user, bb_msg, not from_host)
# don't process it again!
return true
# lucy punchback :3
"player_punch":
if not DATA.has("nya"): punched(PACKET_SENDER, DATA["punch_type"])
# still get punched!
return false
# fall through to default code
return false
func bbcode_changes(): func bbcode_changes():
if srv_allow_bbcode and allow_intrusive_bbcode: if allow_intrusive_bbcode and srv_bbcode:
allowed_tags = [ allowed_tags = [
"b", "i", "u", "s", "color", "b", "i", "u", "s", "color",
"wave", "rainbow", "shake", "tornado", "font"] "wave", "rainbow", "shake", "tornado", "font"]
@@ -117,64 +453,22 @@ func bbcode_changes():
"b", "i", "u", "s", "color"] "b", "i", "u", "s", "color"]
if lucys_menu != null: lucys_menu.update() if lucys_menu != null: lucys_menu.update()
func set_log_messages(val):
log_messages = val
Network.LUCY_LOG_MESSAGES = val
func set_allow_intrusive_bbcode(bbcode):
allow_intrusive_bbcode = bbcode
if Network.GAME_MASTER or not ingame:
self.srv_allow_bbcode = bbcode
else: bbcode_changes()
func set_srv_bbcode(bbcode):
if Network.GAME_MASTER and not Network.PLAYING_OFFLINE: send_server_sync_actor()
srv_allow_bbcode = bbcode
bbcode_changes()
func set_server_name(name):
custom_server_name = name
Network.LUCY_SRV_NAME = name
func set_join_message(msg):
server_join_message = msg
func set_frame_packets(val):
frame_packets = val
Network.LUCY_FRAME_PACKETS = val
func set_bulk_packets(val):
bulk_packets = val
Network.LUCY_BULK_PACKETS = val
func set_bulk_interval(val):
bulk_interval = val
Network.LUCY_BULK_INTERVAL = val
Network.BULK_PACKET_READ_TIMER = 0
func set_full_interval(val):
full_interval = val
Network.LUCY_BULK_FULL_INTERVAL = val
Network.LUCY_BULK_FULL_TIMER = 0
func set_custom_color(val):
custom_color = Color(val) if Color(val) != Color("d5aa73") else Color("739ed5")
custom_color.a = 1
func _ready(): func _ready():
print("[LUCY] Loaded LucysTools") print("[LUCY] Loaded LucysTools 0.6.0")
load_settings() load_settings()
root.connect("child_entered_tree", self, "_on_enter") root.connect("child_entered_tree", self, "_on_enter")
Network.connect("_new_player_join", self, "new_player") Network.connect("_new_player_join", self, "new_player")
PlayerData.connect("_punched", self, "punched") Steam.connect("lobby_created", self, "inject_lobby_data")
Network.connect("_instance_actor", self, "_instance_actor")
func send_server_sync_actor(to = "peers"): func inject_lobby_data(connect, lobby_id):
if connect != 1: return
if custom_server_name != "":
Steam.setLobbyData(lobby_id, "bbcode_lobby_name", custom_server_name)
func send_lucy_sync(to = "peers"):
if not Network.GAME_MASTER: return if not Network.GAME_MASTER: return
var dict = {"actor_type": "lucy_fake_actor", "at": Vector3.ZERO, "zone": "", "actor_id": 0, "creator_id": Network.STEAM_ID, "data": { Network._send_P2P_Packet({"type": "lucy_packet", "srv_bbcode": srv_bbcode}, to, Network.CHANNELS.GAME_STATE)
"allow_bbcode": allow_bbcode
}}
Network._send_P2P_Packet({"type": "instance_actor", "params": dict}, to, 2)
func _instance_actor(dict):
if dict["actor_type"] != "lucy_fake_actor": return
var sender = Network.LUCY_INSTANCE_SENDER
Network.LUCY_INSTANCE_SENDER = 0
if sender != Network.KNOWN_GAME_MASTER or Network.GAME_MASTER: return
var data = dict["data"]
self.srv_allow_bbcode = data["allow_bbcode"]
func get_player() -> Actor: func get_player() -> Actor:
for p in get_tree().get_nodes_in_group("player"): for p in get_tree().get_nodes_in_group("player"):
@@ -182,26 +476,29 @@ func get_player() -> Actor:
return p return p
return null return null
func punched(from, type): func punched(puncher_id, type):
print("[LUCY] punched!") print("[LUCY] punch from ", Network._get_username_from_id(puncher_id))
if not do_punchback: return if not do_punchback: return
if Network.LUCY_PUNCHED_ME == 0 or Network.LUCY_PUNCHED_ME == Network.STEAM_ID: return if puncher_id == 0 or puncher_id == Network.STEAM_ID: return
var punched_me = null
for p in get_tree().get_nodes_in_group("player"):
if p.owner_id == Network.LUCY_PUNCHED_ME: punched_me = p
if punched_me == null: return
if punched_me.controlled: return
print("[LUCY] punching back...") print("[LUCY] punching back...")
Network.LUCY_PUNCHED_ME = 0 Network._send_P2P_Packet({"type": "player_punch", "from_pos": get_player().global_transform.origin, "punch_type": type, "nya": "nya"}, str(puncher_id), 2, Network.CHANNELS.ACTOR_ACTION)
Network._send_P2P_Packet({"type": "player_punch", "from": get_player().global_transform.origin, "player": Network.STEAM_ID, "punch_type": type, "nya": "nya"}, str(punched_me.owner_id), 2)
func new_player(id): func new_player(id):
print("[LUCY] new player!") print("[LUCY] new player!")
if server_join_message.empty() or not Network.GAME_MASTER: return if server_join_message.empty() or not Network.GAME_MASTER: return
print("[LUCY] sending join message") print("[LUCY] sending join message")
Network._send_message(server_join_message) var bb_msg = bbcode_process(server_join_message, 512)
send_server_sync_actor(str(id)) if not bug_bbcode:
lucy_send_message(bb_msg.fin, bb_msg.stripped, false)
else:
var evil_color = "00ff0000]"\
+ "[color=#ffeed5]"\
+ bb_msg.fin\
+ "[/color]"
if bb_msg.fin != "":
lucy_send_message("", "%u", false, evil_color)
send_lucy_sync(str(id))
func _on_enter(node: Node): func _on_enter(node: Node):
if node.name == "main_menu": if node.name == "main_menu":
@@ -215,19 +512,17 @@ func _on_enter(node: Node):
lucys_menu.MANAGER = self lucys_menu.MANAGER = self
node.add_child(lucys_menu) node.add_child(lucys_menu)
ingame = true ingame = true
# retrigger setter
self.srv_allow_bbcode = false
self.allow_intrusive_bbcode = allow_intrusive_bbcode self.allow_intrusive_bbcode = allow_intrusive_bbcode
lucys_menu.setup() lucys_menu.setup()
const save_keys = [ const save_keys = [
"do_punchback", "allow_bbcode", "do_punchback", "allow_bbcode",
"custom_server_name", "server_join_message", "custom_server_name", "server_join_message",
"frame_packets", "bulk_packets",
"bulk_interval", "full_interval",
"custom_color_enabled", "custom_color", "custom_color_enabled", "custom_color",
"log_messages", "custom_name", "log_messages", "custom_name",
"allow_intrusive_bbcode" "allow_intrusive_bbcode", "DEBUG",
"bug_bbcode", "custom_text_color",
"custom_text_color_enabled"
] ]
func load_settings(): func load_settings():
@@ -244,10 +539,11 @@ func load_settings():
func save_settings(): func save_settings():
print("[LUCY] Saving settings") print("[LUCY] Saving settings")
custom_color = Color(custom_color).to_html()
var settings = {} var settings = {}
for key in save_keys: for key in save_keys:
if key in ["custom_color", "custom_text_color"]:
settings[key] = self[key].to_html()
else:
settings[key] = self[key] settings[key] = self[key]
var file = File.new() var file = File.new()

View File

@@ -14,6 +14,8 @@ public class Mod : IMod {
ModInterface = modInterface; ModInterface = modInterface;
modInterface.RegisterScriptMod(new LucysChatChanges()); modInterface.RegisterScriptMod(new LucysChatChanges());
modInterface.RegisterScriptMod(new LucysNetFixes()); modInterface.RegisterScriptMod(new LucysNetFixes());
modInterface.RegisterScriptMod(new LucyServerBrowserChanges());
modInterface.RegisterScriptMod(new LucyMainMenuChanges());
} }
public void Dispose(){} public void Dispose(){}
@@ -25,6 +27,188 @@ public record CodeChange {
public required Token[] code_to_add; public required Token[] code_to_add;
} }
public class LucyServerBrowserChanges: IScriptMod
{
bool IScriptMod.ShouldRun(string path) => path == "res://Scenes/Menus/Main Menu/ServerButton/server_button.gdc";
CodeChange[] changes = {
new CodeChange {
name = "server button arg",
// , age_limit, dated, banned END
multitoken_prefix = new Func<Token, bool>[] {
t => t.Type == TokenType.Comma,
t => t is IdentifierToken {Name: "age_limit"},
t => t.Type == TokenType.Comma,
t => t is IdentifierToken {Name: "dated"},
t => t.Type == TokenType.Comma,
t => t is IdentifierToken {Name: "banned"},
},
// , lucy_display
code_to_add = new Token[] {
new Token(TokenType.Comma),
new IdentifierToken("lucy_display"),
new Token(TokenType.OpAssign),
new ConstantToken(new StringVariant("")),
}
},
new CodeChange {
name = "server button load",
// display_name.replace(']', '')
// END
multitoken_prefix = new Func<Token, bool>[] {
t => t is IdentifierToken {Name: "display_name"},
t => t.Type == TokenType.Period,
t => t is IdentifierToken {Name: "replace"},
t => t.Type == TokenType.ParenthesisOpen,
t => t is ConstantToken {Value:StringVariant{Value:"]"}},
t => t.Type == TokenType.Comma,
t => t is ConstantToken,
t => t.Type == TokenType.ParenthesisClose,
t => t.Type == TokenType.Newline,
},
// if lucy_display != "": display_name = lucy_display
code_to_add = new Token[] {
new Token(TokenType.CfIf),
new IdentifierToken("lucy_display"),
new Token(TokenType.OpNotEqual),
new ConstantToken(new StringVariant("")),
new Token(TokenType.Colon),
new IdentifierToken("display_name"),
new Token(TokenType.OpAssign),
new IdentifierToken("lucy_display"),
new Token(TokenType.Newline, 1),
}
},
};
IEnumerable<Token> IScriptMod.Modify(string path, IEnumerable<Token> tokens)
{
var pending_changes = changes
.Select(c => (c, new MultiTokenWaiter(c.multitoken_prefix)))
.ToList();
// I'm sure there's a better way to do this
// with list comprehension stuff, but my
// C# is too rusty
foreach (var token in tokens) {
var had_change = false;
foreach (var (change, waiter) in pending_changes) {
if (waiter.Check(token)) {
Mod.ModInterface.Logger.Information($"Adding Lucy server button mod {change.name}");
yield return token;
foreach (var t in change.code_to_add) yield return t;
had_change = true;
break;
}
}
if (!had_change) yield return token;
}
}
}
public class LucyMainMenuChanges: IScriptMod
{
bool IScriptMod.ShouldRun(string path) => path == "res://Scenes/Menus/Main Menu/main_menu.gdc";
CodeChange[] changes = {
new CodeChange {
name = "server button lucy_display get",
// if $"%hidenames".pressed: lobby_custom_name = ""
// END
multitoken_prefix = new Func<Token, bool>[] {
t => t.Type == TokenType.CfIf,
t => t.Type == TokenType.Dollar,
t => t is ConstantToken {Value:StringVariant{Value:"%hidenames"}},
t => t.Type == TokenType.Period,
t => t is IdentifierToken {Name: "pressed"},
t => t.Type == TokenType.Colon,
t => t is IdentifierToken {Name: "lobby_custom_name"},
t => t.Type == TokenType.OpAssign,
t => t.Type == TokenType.Constant,
t => t.Type == TokenType.Newline,
},
// var lucy_display = ""
// if not $"%hidenames".pressed:
// lucy_display = Steam.getLobbyData(lobby, "bbcode_lobby_name")
code_to_add = new Token[] {
new Token(TokenType.PrVar),
new IdentifierToken("lucy_display"),
new Token(TokenType.OpAssign),
new ConstantToken(new StringVariant("")),
new Token(TokenType.Newline, 2),
new Token(TokenType.CfIf),
new Token(TokenType.OpNot),
new Token(TokenType.Dollar),
new ConstantToken(new StringVariant("%hidenames")),
new Token(TokenType.Period),
new IdentifierToken("pressed"),
new Token(TokenType.Colon),
new Token(TokenType.Newline, 3),
new IdentifierToken("lucy_display"),
new Token(TokenType.OpAssign),
new IdentifierToken("Steam"),
new Token(TokenType.Period),
new IdentifierToken("getLobbyData"),
new Token(TokenType.ParenthesisOpen),
new IdentifierToken("lobby"),
new Token(TokenType.Comma),
new ConstantToken(new StringVariant("bbcode_lobby_name")),
new Token(TokenType.ParenthesisClose),
new Token(TokenType.Newline, 2)
}
},
new CodeChange {
name = "server button lucy_display arg",
// lobby_cap, lobby_age, dated, banned END
multitoken_prefix = new Func<Token, bool>[] {
t => t is IdentifierToken {Name: "lobby_cap"},
t => t.Type == TokenType.Comma,
t => t is IdentifierToken {Name: "lobby_age"},
t => t.Type == TokenType.Comma,
t => t is IdentifierToken {Name: "dated"},
t => t.Type == TokenType.Comma,
t => t is IdentifierToken {Name: "banned"},
},
// , lucy_display END
code_to_add = new Token[] {
new Token(TokenType.Comma),
new IdentifierToken("lucy_display"),
}
},
};
IEnumerable<Token> IScriptMod.Modify(string path, IEnumerable<Token> tokens)
{
var pending_changes = changes
.Select(c => (c, new MultiTokenWaiter(c.multitoken_prefix)))
.ToList();
// I'm sure there's a better way to do this
// with list comprehension stuff, but my
// C# is too rusty
foreach (var token in tokens) {
var had_change = false;
foreach (var (change, waiter) in pending_changes) {
if (waiter.Check(token)) {
Mod.ModInterface.Logger.Information($"Adding Lucy server button mod {change.name}");
yield return token;
foreach (var t in change.code_to_add) yield return t;
had_change = true;
break;
}
}
if (!had_change) yield return token;
}
}
}
public class LucysChatChanges : IScriptMod public class LucysChatChanges : IScriptMod
{ {
bool IScriptMod.ShouldRun(string path) => path == "res://Scenes/HUD/playerhud.gdc"; bool IScriptMod.ShouldRun(string path) => path == "res://Scenes/HUD/playerhud.gdc";
@@ -66,10 +250,10 @@ public class LucysChatChanges : IScriptMod
t => t is IdentifierToken {Name: "suffix"}, t => t is IdentifierToken {Name: "suffix"},
t => t.Type == TokenType.Newline, t => t.Type == TokenType.Newline,
}, },
// if $"/root/LucyLucysTools": // if $"/root/LucyLucysTools".INTERCEPT_SEND_MSG:
// var tmp = $"/root/LucyLucysTools".process_message(lit_text, final_text, prefix, suffix, endcap, username, spoken_text) // var tmp = $"/root/LucyLucysTools".process_message(lit_text, final, prefix, suffix, endcap, final_color, spoken_text, chat_local, colon, self)
// final = tmp[0] // if tmp[0]: return
// spoken_text = tmp[1] // final_color = tmp[1]
// END // END
code_to_add = new Token[] { code_to_add = new Token[] {
new Token(TokenType.CfIf), new Token(TokenType.CfIf),
@@ -88,7 +272,7 @@ public class LucysChatChanges : IScriptMod
new Token(TokenType.ParenthesisOpen), new Token(TokenType.ParenthesisOpen),
new IdentifierToken("lit_text"), new IdentifierToken("lit_text"),
new Token(TokenType.Comma), new Token(TokenType.Comma),
new IdentifierToken("final_text"), new IdentifierToken("final"),
new Token(TokenType.Comma), new Token(TokenType.Comma),
new IdentifierToken("prefix"), new IdentifierToken("prefix"),
new Token(TokenType.Comma), new Token(TokenType.Comma),
@@ -96,23 +280,26 @@ public class LucysChatChanges : IScriptMod
new Token(TokenType.Comma), new Token(TokenType.Comma),
new IdentifierToken("endcap"), new IdentifierToken("endcap"),
new Token(TokenType.Comma), new Token(TokenType.Comma),
new IdentifierToken("username"),
new Token(TokenType.Comma),
new IdentifierToken("final_color"),
new Token(TokenType.Comma),
new IdentifierToken("spoken_text"), new IdentifierToken("spoken_text"),
new Token(TokenType.Comma),
new IdentifierToken("chat_local"),
new Token(TokenType.Comma),
new IdentifierToken("colon"),
new Token(TokenType.Comma),
new Token(TokenType.Self),
new Token(TokenType.ParenthesisClose), new Token(TokenType.ParenthesisClose),
new Token(TokenType.Newline, 2), new Token(TokenType.Newline, 2),
new IdentifierToken("final"), new Token(TokenType.CfIf),
new Token(TokenType.OpAssign),
new IdentifierToken("tmp"), new IdentifierToken("tmp"),
new Token(TokenType.BracketOpen), new Token(TokenType.BracketOpen),
new ConstantToken(new IntVariant(0)), new ConstantToken(new IntVariant(0)),
new Token(TokenType.BracketClose), new Token(TokenType.BracketClose),
new Token(TokenType.Colon),
new Token(TokenType.CfReturn),
new Token(TokenType.Newline, 2), new Token(TokenType.Newline, 2),
new IdentifierToken("spoken_text"), new IdentifierToken("final_color"),
new Token(TokenType.OpAssign), new Token(TokenType.OpAssign),
new IdentifierToken("tmp"), new IdentifierToken("tmp"),
new Token(TokenType.BracketOpen), new Token(TokenType.BracketOpen),
@@ -155,656 +342,36 @@ public class LucysNetFixes : IScriptMod {
CodeChange[] changes = { CodeChange[] changes = {
new CodeChange { new CodeChange {
name = "send_message channel 2", name = "read packet intercept",
// MESSAGE_ZONE, "zone_owner": PlayerData.player_saved_zone_owner}, "peers", 2) // FLUSH_PACKET_INFORMATION[PACKET_SENDER] += 1
multitoken_prefix = new Func<Token, bool>[] {
t => t is IdentifierToken {Name: "MESSAGE_ZONE"},
t => t.Type == TokenType.Comma,
t => t is ConstantToken {Value:StringVariant{Value: "zone_owner"}},
t => t.Type == TokenType.Colon,
t => t is IdentifierToken {Name: "PlayerData"},
t => t.Type == TokenType.Period,
t => t is IdentifierToken {Name: "player_saved_zone_owner"},
t => t.Type == TokenType.CurlyBracketClose,
t => t.Type == TokenType.Comma,
t => t is ConstantToken {Value:StringVariant{Value: "peers"}},
t => t.Type == TokenType.Comma,
t => t is ConstantToken {Value:IntVariant{Value: 2}},
},
// , 2 END
code_to_add = new Token[] {
new Token(TokenType.Comma),
new ConstantToken(new IntVariant(2)),
}
},
new CodeChange {
name = "instance_actor",
// "instance_actor":
// END // END
multitoken_prefix = new Func<Token, bool>[] { multitoken_prefix = new Func<Token, bool>[] {
t => t is ConstantToken {Value:StringVariant{Value: "instance_actor"}}, t => t is IdentifierToken {Name: "FLUSH_PACKET_INFORMATION"},
t => t.Type == TokenType.Colon,
t => t.Type == TokenType.Newline,
},
// LUCY_INSTANCE_SENDER = packet_sender
// END
code_to_add = new Token[] {
new IdentifierToken("LUCY_INSTANCE_SENDER"),
new Token(TokenType.OpAssign),
new IdentifierToken("packet_sender"),
new Token(TokenType.Newline, 4),
}
},
new CodeChange {
name = "kick",
// "kick":
// END
multitoken_prefix = new Func<Token, bool>[] {
t => t is ConstantToken {Value:StringVariant{Value: "kick"}},
t => t.Type == TokenType.Colon,
t => t.Type == TokenType.Newline
},
// if LUCY_LOG_MESSAGES: print("[KICK from", _get_username_from_id(packet_sender), " (", packet_sender, ")]")
// if GAME_MASTER: return
// if packet_sender != KNOWN_GAME_MASTER: return
// END
code_to_add = new Token[] {
new Token(TokenType.CfIf),
new IdentifierToken("LUCY_LOG_MESSAGES"),
new Token(TokenType.Colon),
new Token(TokenType.BuiltInFunc, (uint)BuiltinFunction.TextPrint),
new Token(TokenType.ParenthesisOpen),
new ConstantToken(new StringVariant("[KICK from ")),
new Token(TokenType.Comma),
new IdentifierToken("_get_username_from_id"),
new Token(TokenType.ParenthesisOpen),
new IdentifierToken("packet_sender"),
new Token(TokenType.ParenthesisClose),
new Token(TokenType.Comma),
new ConstantToken(new StringVariant(" (")),
new Token(TokenType.Comma),
new IdentifierToken("packet_sender"),
new Token(TokenType.Comma),
new ConstantToken(new StringVariant(")]")),
new Token(TokenType.ParenthesisClose),
new Token(TokenType.Newline, 4),
new Token(TokenType.CfIf),
new IdentifierToken("GAME_MASTER"),
new Token(TokenType.Colon),
new Token(TokenType.CfReturn),
new Token(TokenType.Newline, 4),
new Token(TokenType.CfIf),
new IdentifierToken("packet_sender"),
new Token(TokenType.OpNotEqual),
new IdentifierToken("KNOWN_GAME_MASTER"),
new Token(TokenType.Colon),
new Token(TokenType.CfReturn),
new Token(TokenType.Newline, 4),
}
},
new CodeChange {
name = "ban",
// "ban":
// END
multitoken_prefix = new Func<Token, bool>[] {
t => t is ConstantToken {Value:StringVariant{Value: "ban"}},
t => t.Type == TokenType.Colon,
t => t.Type == TokenType.Newline
},
// if LUCY_LOG_MESSAGES: print("[BAN from", _get_username_from_id(packet_sender), " (", packet_sender, ")]")
// if GAME_MASTER: return
// if packet_sender != KNOWN_GAME_MASTER: return
// END
code_to_add = new Token[] {
new Token(TokenType.CfIf),
new IdentifierToken("LUCY_LOG_MESSAGES"),
new Token(TokenType.Colon),
new Token(TokenType.BuiltInFunc, (uint)BuiltinFunction.TextPrint),
new Token(TokenType.ParenthesisOpen),
new ConstantToken(new StringVariant("[BAN from ")),
new Token(TokenType.Comma),
new IdentifierToken("_get_username_from_id"),
new Token(TokenType.ParenthesisOpen),
new IdentifierToken("packet_sender"),
new Token(TokenType.ParenthesisClose),
new Token(TokenType.Comma),
new ConstantToken(new StringVariant(" (")),
new Token(TokenType.Comma),
new IdentifierToken("packet_sender"),
new Token(TokenType.Comma),
new ConstantToken(new StringVariant(")]")),
new Token(TokenType.ParenthesisClose),
new Token(TokenType.Newline, 4),
new Token(TokenType.CfIf),
new IdentifierToken("GAME_MASTER"),
new Token(TokenType.Colon),
new Token(TokenType.CfReturn),
new Token(TokenType.Newline, 4),
new Token(TokenType.CfIf),
new IdentifierToken("packet_sender"),
new Token(TokenType.OpNotEqual),
new IdentifierToken("KNOWN_GAME_MASTER"),
new Token(TokenType.Colon),
new Token(TokenType.CfReturn),
new Token(TokenType.Newline, 4),
}
},
new CodeChange {
name = "punch",
// "player_punch":
// END
multitoken_prefix = new Func<Token, bool>[] {
t => t is ConstantToken {Value:StringVariant{Value: "player_punch"}},
t => t.Type == TokenType.Colon,
t => t.Type == TokenType.Newline
},
// if not DATA.has("nya"): LUCY_PUNCHED_ME = packet_sender
// END
code_to_add = new Token[] {
new Token(TokenType.CfIf),
new Token(TokenType.OpNot),
new IdentifierToken("DATA"),
new Token(TokenType.Period),
new IdentifierToken("has"),
new Token(TokenType.ParenthesisOpen),
new ConstantToken(new StringVariant("nya")),
new Token(TokenType.ParenthesisClose),
new Token(TokenType.Colon),
new IdentifierToken("LUCY_PUNCHED_ME"),
new Token(TokenType.OpAssign),
new IdentifierToken("packet_sender"),
new Token(TokenType.Newline,4),
}
},
new CodeChange {
name = "message",
// "message":
multitoken_prefix = new Func<Token, bool>[] {
t => t is ConstantToken {Value:StringVariant{Value: "message"}},
t => t.Type == TokenType.Colon,
t => t.Type == TokenType.Newline
},
// if LUCY_LOG_MESSAGES: print("[msg ", _get_username_from_id(packet_sender), "] ", DATA.message)
code_to_add = new Token[] {
new Token(TokenType.CfIf),
new IdentifierToken("LUCY_LOG_MESSAGES"),
new Token(TokenType.Colon),
new Token(TokenType.BuiltInFunc, (uint)BuiltinFunction.TextPrint),
new Token(TokenType.ParenthesisOpen),
new ConstantToken(new StringVariant("[msg ")),
new Token(TokenType.Comma),
new IdentifierToken("_get_username_from_id"),
new Token(TokenType.ParenthesisOpen),
new IdentifierToken("packet_sender"),
new Token(TokenType.ParenthesisClose),
new Token(TokenType.Comma),
new ConstantToken(new StringVariant(" (")),
new Token(TokenType.Comma),
new IdentifierToken("packet_sender"),
new Token(TokenType.Comma),
new ConstantToken(new StringVariant(")] ")),
new Token(TokenType.Comma),
new IdentifierToken("DATA"),
new Token(TokenType.Period),
new IdentifierToken("message"),
new Token(TokenType.ParenthesisClose),
new Token(TokenType.Newline, 4),
}
},
new CodeChange {
name = "_read_all_P2P_packets",
// func _read_all_P2P_packets(channel = 0 END
multitoken_prefix = new Func<Token, bool>[] {
t => t.Type == TokenType.PrFunction,
t => t is IdentifierToken {Name: "_read_all_P2P_packets"},
t => t.Type == TokenType.ParenthesisOpen,
t => t.Type == TokenType.Identifier,
t => t.Type == TokenType.OpAssign,
t => t.Type == TokenType.Constant,
},
// , limit = 64):
// var read_count = 0
// while Steam.getAvailableP2PPacketSize(channel) > 0 and read_count < limit:
// _read_P2P_Packet(channel)
// read_count += 1
// LUCY_PACKETS_READ += read_count
// func _old_read_all_P2P_packets(channel = 0 END
code_to_add = new Token[] {
new Token(TokenType.Comma),
new IdentifierToken("limit"),
new Token(TokenType.OpAssign),
new ConstantToken(new IntVariant(64)),
new Token(TokenType.ParenthesisClose),
new Token(TokenType.Colon),
new Token(TokenType.Newline, 1),
new Token(TokenType.PrVar),
new IdentifierToken("read_count"),
new Token(TokenType.OpAssign),
new ConstantToken(new IntVariant(0)),
new Token(TokenType.Newline, 1),
new Token(TokenType.CfWhile),
new IdentifierToken("Steam"),
new Token(TokenType.Period),
new IdentifierToken("getAvailableP2PPacketSize"),
new Token(TokenType.ParenthesisOpen),
new IdentifierToken("channel"),
new Token(TokenType.ParenthesisClose),
new Token(TokenType.OpGreater),
new ConstantToken(new IntVariant(0)),
new Token(TokenType.OpAnd),
new IdentifierToken("read_count"),
new Token(TokenType.OpLess),
new IdentifierToken("limit"),
new Token(TokenType.Colon),
new Token(TokenType.Newline, 2),
new IdentifierToken("_read_P2P_Packet"),
new Token(TokenType.ParenthesisOpen),
new IdentifierToken("channel"),
new Token(TokenType.ParenthesisClose),
new Token(TokenType.Newline, 2),
new IdentifierToken("read_count"),
new Token(TokenType.OpAssignAdd),
new ConstantToken(new IntVariant(1)),
new Token(TokenType.Newline, 1),
new IdentifierToken("LUCY_PACKETS_READ"),
new Token(TokenType.OpAssignAdd),
new IdentifierToken("read_count"),
new Token(TokenType.Newline, 0),
// Give old function new signature, it'll come after in token stream
new Token(TokenType.PrFunction),
new IdentifierToken("_old_read_all_P2P_packets"),
new Token(TokenType.ParenthesisOpen),
new IdentifierToken("channel"),
new Token(TokenType.OpAssign),
new ConstantToken(new IntVariant(0)),
}
},
new CodeChange {
name = "_process",
// func _process(delta):
// if not STEAM_ENABLED: return
// Steam.run_callbacks()
// if STEAM_LOBBY_ID > 0:
// END
multitoken_prefix = new Func<Token, bool>[] {
t => t.Type == TokenType.PrFunction,
t => t is IdentifierToken {Name: "_process"},
t => t.Type == TokenType.ParenthesisOpen,
t => t.Type == TokenType.Identifier,
t => t.Type == TokenType.ParenthesisClose,
t => t.Type == TokenType.Colon,
t => t.Type == TokenType.Newline,
t => t.Type == TokenType.CfIf,
t => t.Type == TokenType.OpNot,
t => t.Type == TokenType.Identifier,
t => t.Type == TokenType.Colon,
t => t.Type == TokenType.CfReturn,
t => t.Type == TokenType.Newline,
t => t.Type == TokenType.Identifier,
t => t.Type == TokenType.Period,
t => t.Type == TokenType.Identifier,
t => t.Type == TokenType.ParenthesisOpen,
t => t.Type == TokenType.ParenthesisClose,
t => t.Type == TokenType.Newline,
t => t.Type == TokenType.CfIf,
t => t.Type == TokenType.Identifier,
t => t.Type == TokenType.OpGreater,
t => t.Type == TokenType.Constant,
t => t.Type == TokenType.Colon,
t => t.Type == TokenType.Newline,
},
// for i in 3: _read_all_P2P_packets(i,LUCY_FRAME_PACKETS)
// return
// if false:
code_to_add = new Token[] {
new Token(TokenType.CfFor),
new IdentifierToken("i"),
new Token(TokenType.OpIn),
new ConstantToken(new IntVariant(3)),
new Token(TokenType.Colon),
new IdentifierToken("_read_all_P2P_packets"),
new Token(TokenType.ParenthesisOpen),
new IdentifierToken("i"),
new Token(TokenType.Comma),
new IdentifierToken("LUCY_FRAME_PACKETS"),
new Token(TokenType.ParenthesisClose),
new Token(TokenType.Newline, 1),
new Token(TokenType.CfReturn),
new Token(TokenType.Newline, 1),
new Token(TokenType.CfIf),
new ConstantToken(new BoolVariant(false)),
new Token(TokenType.Colon),
new Token(TokenType.Newline, 2),
}
},
new CodeChange {
name = "_physics_process",
// func _physics_process(delta):
// if not STEAM_ENABLED: return
// END
multitoken_prefix = new Func<Token, bool>[] {
t => t.Type == TokenType.PrFunction,
t => t is IdentifierToken {Name: "_physics_process"},
t => t.Type == TokenType.ParenthesisOpen,
t => t.Type == TokenType.Identifier,
t => t.Type == TokenType.ParenthesisClose,
t => t.Type == TokenType.Colon,
t => t.Type == TokenType.Newline,
t => t.Type == TokenType.CfIf,
t => t.Type == TokenType.OpNot,
t => t.Type == TokenType.Identifier,
t => t.Type == TokenType.Colon,
t => t.Type == TokenType.CfReturn,
t => t.Type == TokenType.Newline,
},
// var do_print = false
// BULK_PACKET_READ_TIMER -= delta
// if BULK_PACKET_READ_TIMER <= 0:
// print("Bulk Reading Packets.")
// for i in 3: _read_all_P2P_packets(i,LUCY_BULK_PACKETS)
// BULK_PACKET_READ_TIMER = LUCY_BULK_INTERVAL
// do_print = true
// LUCY_BULK_FULL_TIMER -= delta
// if LUCY_BULK_FULL_TIMER <= 0:
// print("Reading all packets.")
// for i in 3: _read_all_P2P_packets(i,1000000)
// LUCY_BULK_FULL_TIMER = LUCY_BULK_FULL_INTERVAL
// do_print = true
// if do_print:
// print("PACKETS ", LUCY_PACKETS_READ)
// LUCY_PACKETS_READ = 0
// return
code_to_add = new Token[] {
// var do_print = false
// BULK_PACKET_READ_TIMER -= delta
// if BULK_PACKET_READ_TIMER <= 0:
// print("Bulk Reading Packets.")
// for i in 3: _read_all_P2P_packets(i,LUCY_BULK_PACKETS)
// BULK_PACKET_READ_TIMER = LUCY_BULK_INTERVAL
// do_print = true
new Token(TokenType.PrVar),
new IdentifierToken("do_print"),
new Token(TokenType.OpAssign),
new ConstantToken(new BoolVariant(false)),
new Token(TokenType.Newline, 1),
new IdentifierToken("BULK_PACKET_READ_TIMER"),
new Token(TokenType.OpAssignSub),
new IdentifierToken("delta"),
new Token(TokenType.Newline, 1),
new Token(TokenType.CfIf),
new IdentifierToken("BULK_PACKET_READ_TIMER"),
new Token(TokenType.OpLessEqual),
new ConstantToken(new IntVariant(0)),
new Token(TokenType.Colon),
new Token(TokenType.Newline, 2),
new Token(TokenType.BuiltInFunc, (uint)BuiltinFunction.TextPrint),
new Token(TokenType.ParenthesisOpen),
new ConstantToken(new StringVariant("Bulk Reading Packets.")),
new Token(TokenType.ParenthesisClose),
new Token(TokenType.Newline, 2),
new Token(TokenType.CfFor),
new IdentifierToken("i"),
new Token(TokenType.OpIn),
new ConstantToken(new IntVariant(3)),
new Token(TokenType.Colon),
new IdentifierToken("_read_all_P2P_packets"),
new Token(TokenType.ParenthesisOpen),
new IdentifierToken("i"),
new Token(TokenType.Comma),
new IdentifierToken("LUCY_BULK_PACKETS"),
new Token(TokenType.ParenthesisClose),
new Token(TokenType.Newline, 2),
new IdentifierToken("BULK_PACKET_READ_TIMER"),
new Token(TokenType.OpAssign),
new IdentifierToken("LUCY_BULK_INTERVAL"),
new Token(TokenType.Newline, 2),
new IdentifierToken("do_print"),
new Token(TokenType.OpAssign),
new ConstantToken(new BoolVariant(true)),
new Token(TokenType.Newline, 1),
// LUCY_BULK_FULL_TIMER -= delta
// if LUCY_BULK_FULL_TIMER <= 0:
// print("Reading all packets.")
// for i in 3: _read_all_P2P_packets(i,1000000)
// LUCY_BULK_FULL_TIMER = LUCY_BULK_FULL_INTERVAL
// do_print = true
new IdentifierToken("LUCY_BULK_FULL_TIMER"),
new Token(TokenType.OpAssignSub),
new IdentifierToken("delta"),
new Token(TokenType.Newline, 1),
new Token(TokenType.CfIf),
new IdentifierToken("LUCY_BULK_FULL_TIMER"),
new Token(TokenType.OpLessEqual),
new ConstantToken(new IntVariant(0)),
new Token(TokenType.Colon),
new Token(TokenType.Newline, 2),
new Token(TokenType.BuiltInFunc, (uint)BuiltinFunction.TextPrint),
new Token(TokenType.ParenthesisOpen),
new ConstantToken(new StringVariant("Reading all packets.")),
new Token(TokenType.ParenthesisClose),
new Token(TokenType.Newline, 2),
new Token(TokenType.CfFor),
new IdentifierToken("i"),
new Token(TokenType.OpIn),
new ConstantToken(new IntVariant(3)),
new Token(TokenType.Colon),
new IdentifierToken("_read_all_P2P_packets"),
new Token(TokenType.ParenthesisOpen),
new IdentifierToken("i"),
new Token(TokenType.Comma),
new ConstantToken(new IntVariant(1000000)),
new Token(TokenType.ParenthesisClose),
new Token(TokenType.Newline, 2),
new IdentifierToken("LUCY_BULK_FULL_TIMER"),
new Token(TokenType.OpAssign),
new IdentifierToken("LUCY_BULK_FULL_INTERVAL"),
new Token(TokenType.Newline, 2),
new IdentifierToken("do_print"),
new Token(TokenType.OpAssign),
new ConstantToken(new BoolVariant(true)),
new Token(TokenType.Newline, 1),
// if do_print:
// print("PACKETS ", LUCY_PACKETS_READ)
// LUCY_PACKETS_READ = 0
new Token(TokenType.CfIf),
new IdentifierToken("do_print"),
new Token(TokenType.Colon),
new Token(TokenType.Newline, 2),
new Token(TokenType.BuiltInFunc, (uint)BuiltinFunction.TextPrint),
new Token(TokenType.ParenthesisOpen),
new ConstantToken(new StringVariant("PACKETS ")),
new Token(TokenType.Comma),
new IdentifierToken("LUCY_PACKETS_READ"),
new Token(TokenType.ParenthesisClose),
new Token(TokenType.Newline, 2),
new IdentifierToken("LUCY_PACKETS_READ"),
new Token(TokenType.OpAssign),
new ConstantToken(new IntVariant(0)),
new Token(TokenType.Newline, 1),
// return
new Token(TokenType.CfReturn),
new Token(TokenType.Newline, 1),
}
},
new CodeChange {
name = "new globals",
// var REPLICATIONS_RECIEVED = []
// END
multitoken_prefix = new Func<Token, bool>[] {
t => t.Type == TokenType.PrVar,
t => t is IdentifierToken {Name: "REPLICATIONS_RECIEVED"},
t => t.Type == TokenType.OpAssign,
t => t.Type == TokenType.BracketOpen, t => t.Type == TokenType.BracketOpen,
t => t is IdentifierToken {Name: "PACKET_SENDER"},
t => t.Type == TokenType.BracketClose, t => t.Type == TokenType.BracketClose,
t => t.Type == TokenType.OpAssignAdd,
t => t is ConstantToken {Value:IntVariant{Value: 1}},
t => t.Type == TokenType.Newline, t => t.Type == TokenType.Newline,
}, },
// var LUCY_PACKETS_READ = 0 // if $"/root/LucyLucysTools".process_read(DATA, PACKET_SENDER, from_host): return
// var LUCY_BULK_FULL_TIMER = 0
// var LUCY_FRAME_PACKETS = 32
// var LUCY_BULK_PACKETS = 128
// var LUCY_BULK_INTERVAL = 0.8
// var LUCY_BULK_FULL_INTERVAL = 6.4
// var LUCY_SRV_NAME = ""
// var LUCY_PUNCHED_ME = 0
// var LUCY_INSTANCE_SENDER = 0
// var LUCY_LOG_MESSAGES = false
// END // END
code_to_add = new Token[] {
new Token(TokenType.PrVar),
new IdentifierToken("LUCY_PACKETS_READ"),
new Token(TokenType.OpAssign),
new ConstantToken(new IntVariant(0)),
new Token(TokenType.Newline, 0),
new Token(TokenType.PrVar),
new IdentifierToken("LUCY_BULK_FULL_TIMER"),
new Token(TokenType.OpAssign),
new ConstantToken(new IntVariant(0)),
new Token(TokenType.Newline, 0),
new Token(TokenType.PrVar),
new IdentifierToken("LUCY_FRAME_PACKETS"),
new Token(TokenType.OpAssign),
new ConstantToken(new IntVariant(32)),
new Token(TokenType.Newline, 0),
new Token(TokenType.PrVar),
new IdentifierToken("LUCY_BULK_PACKETS"),
new Token(TokenType.OpAssign),
new ConstantToken(new IntVariant(128)),
new Token(TokenType.Newline, 0),
new Token(TokenType.PrVar),
new IdentifierToken("LUCY_BULK_INTERVAL"),
new Token(TokenType.OpAssign),
new ConstantToken(new RealVariant(0.8)),
new Token(TokenType.Newline, 0),
new Token(TokenType.PrVar),
new IdentifierToken("LUCY_BULK_FULL_INTERVAL"),
new Token(TokenType.OpAssign),
new ConstantToken(new RealVariant(6.4)),
new Token(TokenType.Newline, 0),
new Token(TokenType.PrVar),
new IdentifierToken("LUCY_SRV_NAME"),
new Token(TokenType.OpAssign),
new ConstantToken(new StringVariant("")),
new Token(TokenType.Newline, 0),
new Token(TokenType.PrVar),
new IdentifierToken("LUCY_PUNCHED_ME"),
new Token(TokenType.OpAssign),
new ConstantToken(new IntVariant(0)),
new Token(TokenType.Newline, 0),
new Token(TokenType.PrVar),
new IdentifierToken("LUCY_INSTANCE_SENDER"),
new Token(TokenType.OpAssign),
new ConstantToken(new IntVariant(0)),
new Token(TokenType.Newline, 0),
new Token(TokenType.PrVar),
new IdentifierToken("LUCY_LOG_MESSAGES"),
new Token(TokenType.OpAssign),
new ConstantToken(new BoolVariant(false)),
new Token(TokenType.Newline, 0),
}
},
new CodeChange {
name = "packet sender",
// if PACKET.empty():
// print("Error! Empty Packet!")
// END
multitoken_prefix = new Func<Token, bool>[] {
t => t is IdentifierToken {Name: "PACKET"},
t => t.Type == TokenType.Period,
t => t is IdentifierToken {Name: "empty"},
t => t.Type == TokenType.ParenthesisOpen,
t => t.Type == TokenType.ParenthesisClose,
t => t.Type == TokenType.Colon,
t => t.Type == TokenType.Newline,
t => t.Type == TokenType.BuiltInFunc,
t => t.Type == TokenType.ParenthesisOpen,
t => t.Type == TokenType.Constant,
t => t.Type == TokenType.ParenthesisClose,
t => t.Type == TokenType.Newline,
},
// var packet_sender = PACKET['steam_id_remote']
// END
code_to_add = new Token[] {
new Token(TokenType.PrVar),
new IdentifierToken("packet_sender"),
new Token(TokenType.OpAssign),
new IdentifierToken("PACKET"),
new Token(TokenType.BracketOpen),
new ConstantToken(new StringVariant("steam_id_remote")),
new Token(TokenType.BracketClose),
new Token(TokenType.Newline, 2),
}
},
new CodeChange {
name = "set lobby name",
// Steam.setLobbyData(lobby_id, "name", str(STEAM_USERNAME) END
multitoken_prefix = new Func<Token, bool>[] {
t => t is IdentifierToken {Name: "setLobbyData"},
t => t.Type == TokenType.ParenthesisOpen,
t => t is IdentifierToken {Name: "lobby_id"},
t => t.Type == TokenType.Comma,
t => t.Type == TokenType.Constant,
t => t.Type == TokenType.Comma,
t => t.Type == TokenType.BuiltInFunc,
t => t.Type == TokenType.ParenthesisOpen,
t => t is IdentifierToken {Name: "STEAM_USERNAME"},
t => t.Type == TokenType.ParenthesisClose,
},
// if LUCY_SRV_NAME == "" else LUCY_SRV_NAME END
code_to_add = new Token[] { code_to_add = new Token[] {
new Token(TokenType.CfIf), new Token(TokenType.CfIf),
new IdentifierToken("LUCY_SRV_NAME"), new Token(TokenType.Dollar),
new Token(TokenType.OpEqual), new ConstantToken(new StringVariant("/root/LucyLucysTools")),
new ConstantToken(new StringVariant("")), new Token(TokenType.Period),
new Token(TokenType.CfElse), new IdentifierToken("process_read"),
new IdentifierToken("LUCY_SRV_NAME"), new Token(TokenType.ParenthesisOpen),
new IdentifierToken("DATA"),
new Token(TokenType.Comma),
new IdentifierToken("PACKET_SENDER"),
new Token(TokenType.Comma),
new IdentifierToken("from_host"),
new Token(TokenType.ParenthesisClose),
new Token(TokenType.Colon),
new Token(TokenType.CfReturn),
new Token(TokenType.Newline, 2),
} }
}, },
}; };

View File

@@ -3,33 +3,27 @@ LucysTools
Uses GDWeave. Uses GDWeave.
Client Features: Client Features:
- Makes the client (tunably) read all packets. This fixes chat messages dropping.
- Optionally knocks people back when they punch you. - Optionally knocks people back when they punch you.
- Lets you clear gamechat - Lets you clear gamechat
- Sends messages on P2P channel 2 (This should make your messages more reliable for users who don't have LucysTools) - Allows custom name color (for all users)
- Only the game host can kick/ban you - Allows custom name BBCode (for compatible peers)
- Allows custom name bbcode (and/or custom color) - Allows custom text color (for compatible peers)
- Allows some BBCode in chat: [b], [i], [u], [s], [color] Make sure to close your tags! - Allows BBCode in chat (for compatible peers)
- (Bug BBCode) Allows BBCode in chat for everyone to see
Host Features: Host Features:
- Lets you set a custom server name and message that will be sent when someone joins. - Lets you set a message that will be sent when someone joins.
- Lets you spawn rainclouds & meteors. - Lets you spawn rainclouds & meteors.
- Lets you enable intrusive BBCode ([rainbow], [tornado], [shake], [wave], [font]) in messages. If enabled, other players on the server can use these too. (Not secure or anything, implemented client side) - If intrusive BBCode is enabled, as host 'raw' messages can be sent with a % prefix
- If intrusive BBCode is enabled, 'raw' messages can be sent with a % prefix
Log Features: Info for Modders:
- If you enable "log_messages" in the config file, messages, kicks, and bans will be logged to godot.log along with the user who sent the packet. - If you'd like to make things compatible, servers get a "bbcode_lobby_name" property, and messages have additional "bb_msg" and "bb_user" fields. DM me!
More coming soon! More coming soon!
Probably certainly full of bugs. Probably certainly full of bugs.
Packet options:
- 'Per Frame Packets' is the number of net packets your client will attempt to read per frame.
- 'Bulk Read Packets' is the number of net packets your client will attempt to read per 'Bulk Read Interval' (in seconds)
- 'Full Read Interval' is how often your client will attempt to read *all* net packets (in seconds).
Compatibility: Compatibility:
- Works *only* with WEBFISHING 1.08 - Works *only* with WEBFISHING 1.09
- I haven't tested any other mods with this, but I'm happy to try to make things compatible, submit a bug report with the incompatible mod! (Only mods that have source available) - I haven't tested any other mods with this, but I'm happy to try to make things compatible, submit a bug report with the incompatible mod! (Only mods that have source available)
Bugs: Bugs: