5 Commits
0.4 ... 0.6.1

Author SHA1 Message Date
fc710e0566 0.6.1 2024-11-08 14:36:13 -06:00
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 952 additions and 1064 deletions

View File

@@ -24,3 +24,27 @@ initial release
- bbcode enabled globally
- intrusive bbcode separated
- 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
0.6.1
----
- menu doesn't auto-open if it was closed

View File

@@ -6,34 +6,34 @@ func setup():
get_node("%lucy_bbcode").pressed = MANAGER.allow_bbcode
get_node("%lucy_punchback").pressed = MANAGER.do_punchback
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_preview").bbcode_text = MANAGER.server_join_message
get_node("%lucy_fpackets").value = MANAGER.frame_packets
get_node("%lucy_bpackets").value = MANAGER.bulk_packets
get_node("%lucy_binterval").value = MANAGER.bulk_interval
get_node("%lucy_finterval").value = MANAGER.full_interval
var srv_m_bb = MANAGER.bbcode_process(MANAGER.server_join_message, 512)
get_node("%lucy_servermsg_preview").bbcode_text = srv_m_bb.fin
get_node("%lucy_servermsg_preview2").bbcode_text = srv_m_bb.stripped
get_node("%lucy_intbbcode").pressed = MANAGER.allow_intrusive_bbcode
get_node("%lucy_chatcolor_bool").pressed = MANAGER.custom_color_enabled
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_bug_bb").pressed = MANAGER.bug_bbcode
get_node("%lucy_srv_bbcode").pressed = MANAGER.srv_bbcode
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)
func _on_lucy_name_text_changed(new_text):
var result = MANAGER.bbcode_process(new_text)
#print("[fin] ", result.fin)
#print("[tags] ", result.tags)
#print("[stripped] ", result.stripped)
var result = MANAGER.bbcode_process(new_text, 512)
var lol_steam_username = Network.STEAM_USERNAME.replace("[", "").replace("]", "")
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]"
MANAGER.custom_name_enabled = good
MANAGER.custom_name = result.fin
MANAGER.custom_name = new_text
func _ready():
print("[LUCY] Menu Ready")
MANAGER = $"/root/LucyLucysTools"
get_node("%lucy_bbcode").disabled = MANAGER.host_required and not Network.GAME_MASTER
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
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_clearmeteor").disabled = not Network.GAME_MASTER or not MANAGER.ingame
visible = MANAGER.lucys_menu_visible
var can_spawn = (Network.GAME_MASTER or Network.PLAYING_OFFLINE) and MANAGER.ingame
get_node("%lucy_raincloud").disabled = not can_spawn
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):
if event is InputEventKey and event.scancode == KEY_F5 && event.pressed:
visible = !visible
print("[LUCY] Menu visble: ", visible)
MANAGER.lucys_menu_visible = visible
if event is InputEventKey and event.scancode == KEY_F6 && event.pressed:
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 code = Steam.getLobbyData(Network.STEAM_LOBBY_ID, "code")
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)
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):
MANAGER.do_punchback = button_pressed
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
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
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):
MANAGER.custom_color_enabled = button_pressed
func _on_lucy_chatcolor_color_changed(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):
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():
if not MANAGER.ingame: return
if not MANAGER.ingame or (not Network.GAME_MASTER and not Network.PLAYING_OFFLINE): return
print("[LUCY] Spawning raincloud")
var player = MANAGER.get_player()
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)
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
print("[LUCY] Spawning meteor")
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)
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")
for cloud in get_tree().get_nodes_in_group("raincloud"):
if cloud.controlled == true:
@@ -126,18 +137,17 @@ func _on_lucy_freezerain_pressed():
cloud.decay = false
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")
for cloud in get_tree().get_nodes_in_group("raincloud"):
cloud._deinstantiate(true)
func _on_lucy_clearchat_pressed():
Network.GAMECHAT = ""
Network.LOCAL_GAMECHAT = ""
Network._wipe_chat()
Network.emit_signal("_chat_update")
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")
for meteor in get_tree().get_nodes_in_group("meteor"):
meteor._deinstantiate(true)

View File

@@ -4,112 +4,136 @@
[node name="lucys_menu" type="Control"]
margin_right = 800.0
margin_bottom = 329.0
margin_bottom = 400.0
script = ExtResource( 1 )
[node name="PanelContainer" type="PanelContainer" parent="."]
anchor_right = 1.0
anchor_bottom = 1.0
margin_bottom = 71.0
margin_bottom = 100.0
[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer"]
margin_left = 7.0
margin_top = 7.0
margin_right = 793.0
margin_bottom = 393.0
margin_bottom = 493.0
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer"]
margin_right = 786.0
margin_bottom = 14.0
text = "Lucy's Options - F5 to Toggle Menu"
text = "Lucy's Options 0.6.1 - F5 to Toggle Menu"
[node name="HSeparator" type="HSeparator" parent="PanelContainer/VBoxContainer"]
margin_top = 18.0
margin_right = 786.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_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 )
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer"]
margin_top = 13.0
margin_right = 138.0
margin_right = 89.0
margin_bottom = 27.0
text = "Allow BBCode (Client)"
text = "Allow BBCode"
[node name="lucy_bbcode" type="CheckButton" parent="PanelContainer/VBoxContainer/HFlowContainer"]
unique_name_in_owner = true
margin_left = 142.0
margin_right = 218.0
margin_left = 93.0
margin_right = 169.0
margin_bottom = 40.0
[node name="Label3" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer"]
margin_left = 222.0
margin_left = 173.0
margin_top = 13.0
margin_right = 471.0
margin_right = 372.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"]
unique_name_in_owner = true
margin_left = 475.0
margin_right = 551.0
margin_left = 376.0
margin_right = 452.0
margin_bottom = 40.0
[node name="Label2" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer"]
margin_left = 555.0
[node name="Label5" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer"]
margin_left = 456.0
margin_top = 13.0
margin_right = 690.0
margin_right = 591.0
margin_bottom = 27.0
text = "Punch back on Punch"
[node name="lucy_punchback" type="CheckButton" parent="PanelContainer/VBoxContainer/HFlowContainer"]
unique_name_in_owner = true
margin_left = 694.0
margin_right = 770.0
margin_left = 595.0
margin_right = 671.0
margin_bottom = 40.0
[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_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"]
margin_top = 96.0
margin_top = 158.0
margin_right = 786.0
margin_bottom = 120.0
margin_bottom = 182.0
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"]
unique_name_in_owner = true
margin_left = 139.0
margin_right = 786.0
margin_bottom = 24.0
size_flags_horizontal = 3
@@ -117,9 +141,9 @@ expand_to_text_length = true
placeholder_text = "Name"
[node name="HFlowContainer6" type="HFlowContainer" parent="PanelContainer/VBoxContainer"]
margin_top = 124.0
margin_top = 186.0
margin_right = 786.0
margin_bottom = 138.0
margin_bottom = 200.0
rect_pivot_offset = Vector2( -141, -49 )
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer6"]
@@ -139,25 +163,24 @@ text = "'s Lobby"
scroll_active = false
[node name="HSeparator4" type="HSeparator" parent="PanelContainer/VBoxContainer"]
margin_top = 142.0
margin_top = 204.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"]
margin_top = 150.0
margin_top = 230.0
margin_right = 786.0
margin_bottom = 174.0
margin_bottom = 254.0
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"]
unique_name_in_owner = true
margin_left = 131.0
margin_right = 786.0
margin_bottom = 24.0
size_flags_horizontal = 3
@@ -165,19 +188,39 @@ expand_to_text_length = true
placeholder_text = "Message"
[node name="HFlowContainer7" type="HFlowContainer" parent="PanelContainer/VBoxContainer"]
margin_top = 178.0
margin_top = 258.0
margin_right = 786.0
margin_bottom = 192.0
margin_bottom = 272.0
rect_pivot_offset = Vector2( -141, -49 )
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer7"]
margin_right = 145.0
margin_right = 109.0
margin_bottom = 14.0
text = "Join Message Preview: "
text = "Normal Preview: "
[node name="lucy_servermsg_preview" type="RichTextLabel" parent="PanelContainer/VBoxContainer/HFlowContainer7"]
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_bottom = 14.0
size_flags_horizontal = 3
@@ -185,82 +228,111 @@ bbcode_enabled = true
scroll_active = false
[node name="HSeparator5" type="HSeparator" parent="PanelContainer/VBoxContainer"]
margin_top = 196.0
margin_top = 294.0
margin_right = 786.0
margin_bottom = 200.0
margin_bottom = 298.0
[node name="HFlowContainer8" type="HFlowContainer" parent="PanelContainer/VBoxContainer"]
margin_top = 204.0
margin_top = 302.0
margin_right = 786.0
margin_bottom = 228.0
margin_bottom = 326.0
rect_pivot_offset = Vector2( -141, -49 )
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer8"]
margin_top = 5.0
margin_right = 107.0
margin_right = 157.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"]
unique_name_in_owner = true
margin_left = 111.0
margin_right = 181.0
margin_left = 161.0
margin_right = 231.0
margin_bottom = 24.0
text = "Enable"
[node name="lucy_chatcolor" type="ColorPickerButton" parent="PanelContainer/VBoxContainer/HFlowContainer8"]
unique_name_in_owner = true
margin_left = 185.0
margin_right = 227.0
margin_left = 235.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
rect_min_size = Vector2( 42, 0 )
edit_alpha = false
[node name="HFlowContainer9" type="HFlowContainer" parent="PanelContainer/VBoxContainer"]
margin_top = 232.0
margin_top = 330.0
margin_right = 786.0
margin_bottom = 256.0
margin_bottom = 344.0
rect_pivot_offset = Vector2( -141, -49 )
hint_tooltip = "Must match Steam username"
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/HFlowContainer9"]
margin_top = 5.0
margin_right = 91.0
margin_bottom = 19.0
text = "Custom Name"
margin_right = 392.0
margin_bottom = 14.0
text = "Custom Name - Must match Steam Name (LucysTools or bug)"
[node name="lucy_namegood" type="RichTextLabel" parent="PanelContainer/VBoxContainer/HFlowContainer9"]
unique_name_in_owner = true
margin_left = 95.0
margin_right = 145.0
margin_bottom = 24.0
margin_left = 396.0
margin_right = 446.0
margin_bottom = 14.0
rect_min_size = Vector2( 50, 0 )
bbcode_enabled = true
bbcode_text = "[color=green]Good[/color]"
text = "Good"
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
margin_left = 149.0
margin_right = 207.0
margin_bottom = 24.0
margin_top = 348.0
margin_right = 786.0
margin_bottom = 372.0
expand_to_text_length = true
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
margin_left = 211.0
margin_top = 376.0
margin_right = 786.0
margin_bottom = 24.0
margin_bottom = 391.0
rect_min_size = Vector2( 0, 15 )
size_flags_horizontal = 3
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
[node name="HFlowContainer2" type="HFlowContainer" parent="PanelContainer/VBoxContainer"]
margin_top = 260.0
[node name="HSeparator6" type="HSeparator" parent="PanelContainer/VBoxContainer"]
margin_top = 395.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"]
margin_right = 76.0
@@ -303,120 +375,21 @@ margin_right = 571.0
margin_bottom = 20.0
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_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/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/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="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_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_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_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,467 @@ const LUCYS_MENU_SCENE = preload("res://mods/Lucy.LucysTools/lucys_menu.tscn")
var lucys_menu = null
onready var root = get_tree().root
var do_punchback = false
var allow_bbcode = 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 INCERCEPT_MSG: bool = false
var INCERCEPT_SEND_MSG: bool = false
var custom_color_enabled = false
var custom_color = Color("009cd0") setget set_custom_color
var do_punchback: bool = false
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_name = ""
var custom_color_enabled: bool = false
var custom_color: Color = Color("009cd0") setget set_custom_color
var allow_intrusive_bbcode = false setget set_allow_intrusive_bbcode
var srv_allow_bbcode = false setget set_srv_bbcode
var custom_name_enabled: bool = false
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
var allowed_tags = ["b", "i", "u", "s", "color"]
var escape_invalid = true
var DEBUG: bool = false
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_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
# i know this sucks
# but i have things to do
func bbcode_recurse(text, data):
var m = bbcode_matcher.search(text)
if m == null:
var escaped = text.replace('[lb]','[').replace('[','[lb]') if escape_invalid else text
data.fin += escaped
data.stripped += escaped
else:
#print("Found ", m.strings, " in '", text, "'")
bbcode_recurse(m.get_string(1), data)
var tag = m.get_string(2)
var junk = m.get_string(3)
var allowed = tag in allowed_tags
if allowed:
data.fin += "[" + tag + junk + "]"
else:
data.fin += "[lb]" + tag + junk + "]"
data.stripped += "[lb]" + tag + junk + "]"
#print("TAG ", m.get_string(2), " JUNK ", m.get_string(3))
data.tags.append([tag, junk])
bbcode_recurse(m.get_string(4), data)
if allowed:
data.fin += "[/" + tag + "]"
else:
data.fin += "[lb]/" + tag + "]"
data.stripped += "[lb]/" + tag + "]"
bbcode_recurse(m.get_string(5), data)
var junk_checkers: Dictionary = {}
func bbcode_process(text):
var alpha_lim := 0.5
var alpha_getter: RegEx = null
func do_alpha_check(junk) -> String:
if not alpha_getter:
alpha_getter = RegEx.new()
alpha_getter.compile("\\s*=\\s*(\\S*)")
var color: Color = Color(alpha_getter.search(junk).get_string(1))
if color.a < alpha_lim:
color.a = alpha_lim
return "=#" + color.to_html()
return ""
func set_check_alpha(val):
check_alpha = val
if val: junk_checkers["color"] = funcref(self, "do_alpha_check")
else: junk_checkers.erase("color")
var INNER_MAX_LEN: int = 0
# ouch oof this sucks
func bbcode_process(text, max_len) -> Dictionary:
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 to_add_full: String
var to_add_stripped: 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)
bbcode_matcher = RegEx.new()
bbcode_matcher.compile("^(.*?)\\[(\\w+?)([^\\]]*)\\](.+?)\\[/\\2\\](.*?)$")
#print("processing '", text, "'")
var data = {"fin": "", "tags": [], "stripped": ""}
bbcode_recurse(text, data)
return data
# Patched Network vars
# var LUCY_PACKETS_READ = 0
# 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
# var LUCY_INSTANCE_SENDER
# var LUCY_LOG_MESSAGES
bbcode_matcher.compile("(.*?)(\\[(\\w+)([^\\[\\]]*?)\\]|\\[/(\\w+)\\])")
var linear_matches: Array = bbcode_matcher.search_all(text)
if linear_matches.empty():
var processed = {"fin": text.replace('[','[lb]'), "stripped": text}
if DEBUG: print("[BBCODE NEW] processed ", processed)
return processed
var tag_stack := []
var full_text_stack := [""]
var stripped_text_stack := [""]
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:
to_add_full = "["+tag+junk+"]" + inner_full + before.replace('[','[lb]') + "[/"+tag+"]"
to_add_stripped = inner_stripped + before.replace('[','[lb]')
else:
to_add_full = inner_full + before.replace('[','[lb]')
to_add_stripped = inner_stripped + before.replace('[','[lb]')
# check length - this sucks but whatever
# just use the stripped version if it's too long.
# whatever
if prev_full.length() + to_add_full.length() > max_len:
to_add_full = to_add_stripped
full_text_stack.push_back(prev_full + to_add_full)
stripped_text_stack.push_back(prev_stripped + to_add_stripped)
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
func process_message(lit_text, final_text, prefix, suffix, endcap, username, final_color, spoken_text):
var thing = {
"lit_text": lit_text, "final_text": final_text, "prefix": prefix, "suffix": suffix,
"endcap": endcap, "username": username, "final_color": final_color,
"srv_allow_bbcode": srv_allow_bbcode, "custom_color_enabled": custom_color_enabled,
"custom_name_enabled": custom_name_enabled, "allow_bbcode": allow_bbcode,
"allowed_tags": allowed_tags
}
#print("FUCK ", thing)
if srv_allow_bbcode and lit_text.begins_with("%"):
return [lit_text.trim_prefix('%'), 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
var name = custom_name if custom_name_enabled else username
var color = custom_color if custom_color_enabled else final_color
var msg = final_text
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 = {
"lit_text": lit_text, "final": final, "prefix": prefix, "suffix": suffix,
"endcap": endcap,
"custom_color_enabled": custom_color_enabled,
"custom_name_enabled": custom_name_enabled, "allow_bbcode": allow_bbcode,
"allowed_tags": allowed_tags
}
print("process_message ", thing)
if (Network.GAME_MASTER or Network.PLAYING_OFFLINE) and lit_text.begins_with("%"):
var bb_dat = bbcode_process(lit_text.trim_prefix('%'), 512)
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
if allow_bbcode:
var p = bbcode_process(lit_text)
if not p.tags.empty():
msg = p.fin
speak = p.stripped
return [
prefix + "[color=#" + str(color.to_html()) + "]" + name + endcap + msg + suffix,
speak
]
if bug_bbcode:
print("Using color field...")
var p = bbcode_process(lit_text, 512)
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
if p.fin != "":
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 = []
var i_hate_regex: RegEx = null
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
# idfk
# the first thing in a color string must be a valid html color,
# followed optionally by a ] (if people are using bug bbcode)
if not i_hate_regex:
i_hate_regex = RegEx.new()
i_hate_regex.compile("^([a-zA-Z0-9]*)(\\]?)(.*)$")
var rmatch: RegExMatch = i_hate_regex.search(color)
var col: Color = rmatch.get_string(1)
var paren = rmatch.get_string(2)
var rest = rmatch.get_string(3)
if paren != "]" and rest != "": paren = "]"
var idfk = 490 - boring_msg.length() - Network.STEAM_USERNAME.length()
var ver_rest = bbcode_process(rest, idfk)
color = col.to_html() + paren + ver_rest.fin.left(idfk)
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():
if srv_allow_bbcode and allow_intrusive_bbcode:
if allow_intrusive_bbcode and srv_bbcode:
allowed_tags = [
"b", "i", "u", "s", "color",
"wave", "rainbow", "shake", "tornado", "font"]
@@ -117,64 +474,22 @@ func bbcode_changes():
"b", "i", "u", "s", "color"]
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():
print("[LUCY] Loaded LucysTools")
print("[LUCY] Loaded LucysTools 0.6.1")
load_settings()
root.connect("child_entered_tree", self, "_on_enter")
Network.connect("_new_player_join", self, "new_player")
PlayerData.connect("_punched", self, "punched")
Network.connect("_instance_actor", self, "_instance_actor")
Steam.connect("lobby_created", self, "inject_lobby_data")
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
var dict = {"actor_type": "lucy_fake_actor", "at": Vector3.ZERO, "zone": "", "actor_id": 0, "creator_id": Network.STEAM_ID, "data": {
"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"]
Network._send_P2P_Packet({"type": "lucy_packet", "srv_bbcode": srv_bbcode}, to, Network.CHANNELS.GAME_STATE)
func get_player() -> Actor:
for p in get_tree().get_nodes_in_group("player"):
@@ -182,26 +497,29 @@ func get_player() -> Actor:
return p
return null
func punched(from, type):
print("[LUCY] punched!")
func punched(puncher_id, type):
print("[LUCY] punch from ", Network._get_username_from_id(puncher_id))
if not do_punchback: return
if Network.LUCY_PUNCHED_ME == 0 or Network.LUCY_PUNCHED_ME == 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
if puncher_id == 0 or puncher_id == Network.STEAM_ID: return
print("[LUCY] punching back...")
Network.LUCY_PUNCHED_ME = 0
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)
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)
func new_player(id):
print("[LUCY] new player!")
if server_join_message.empty() or not Network.GAME_MASTER: return
print("[LUCY] sending join message")
Network._send_message(server_join_message)
send_server_sync_actor(str(id))
var bb_msg = bbcode_process(server_join_message, 512)
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):
if node.name == "main_menu":
@@ -215,19 +533,20 @@ func _on_enter(node: Node):
lucys_menu.MANAGER = self
node.add_child(lucys_menu)
ingame = true
# retrigger setter
self.srv_allow_bbcode = false
self.allow_intrusive_bbcode = allow_intrusive_bbcode
if not Network.GAME_MASTER and not Network.PLAYING_OFFLINE:
self.srv_bbcode = false
lucys_menu.setup()
const save_keys = [
"do_punchback", "allow_bbcode",
"custom_server_name", "server_join_message",
"frame_packets", "bulk_packets",
"bulk_interval", "full_interval",
"custom_color_enabled", "custom_color",
"log_messages", "custom_name",
"allow_intrusive_bbcode"
"allow_intrusive_bbcode", "DEBUG",
"bug_bbcode", "custom_text_color",
"custom_text_color_enabled",
"lucys_menu_visible"
]
func load_settings():
@@ -244,11 +563,12 @@ func load_settings():
func save_settings():
print("[LUCY] Saving settings")
custom_color = Color(custom_color).to_html()
var settings = {}
for key in save_keys:
settings[key] = self[key]
if key in ["custom_color", "custom_text_color"]:
settings[key] = self[key].to_html()
else:
settings[key] = self[key]
var file = File.new()
if file.open(OS.get_executable_path().get_base_dir().plus_file("GDWeave/configs/LucysTools.json"),File.WRITE) == OK:

View File

@@ -14,6 +14,8 @@ public class Mod : IMod {
ModInterface = modInterface;
modInterface.RegisterScriptMod(new LucysChatChanges());
modInterface.RegisterScriptMod(new LucysNetFixes());
modInterface.RegisterScriptMod(new LucyServerBrowserChanges());
modInterface.RegisterScriptMod(new LucyMainMenuChanges());
}
public void Dispose(){}
@@ -25,6 +27,188 @@ public record CodeChange {
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
{
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.Type == TokenType.Newline,
},
// if $"/root/LucyLucysTools":
// var tmp = $"/root/LucyLucysTools".process_message(lit_text, final_text, prefix, suffix, endcap, username, spoken_text)
// final = tmp[0]
// spoken_text = tmp[1]
// if $"/root/LucyLucysTools".INTERCEPT_SEND_MSG:
// var tmp = $"/root/LucyLucysTools".process_message(lit_text, final, prefix, suffix, endcap, final_color, spoken_text, chat_local, colon, self)
// if tmp[0]: return
// final_color = tmp[1]
// END
code_to_add = new Token[] {
new Token(TokenType.CfIf),
@@ -88,7 +272,7 @@ public class LucysChatChanges : IScriptMod
new Token(TokenType.ParenthesisOpen),
new IdentifierToken("lit_text"),
new Token(TokenType.Comma),
new IdentifierToken("final_text"),
new IdentifierToken("final"),
new Token(TokenType.Comma),
new IdentifierToken("prefix"),
new Token(TokenType.Comma),
@@ -96,23 +280,26 @@ public class LucysChatChanges : IScriptMod
new Token(TokenType.Comma),
new IdentifierToken("endcap"),
new Token(TokenType.Comma),
new IdentifierToken("username"),
new Token(TokenType.Comma),
new IdentifierToken("final_color"),
new Token(TokenType.Comma),
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.Newline, 2),
new IdentifierToken("final"),
new Token(TokenType.OpAssign),
new Token(TokenType.CfIf),
new IdentifierToken("tmp"),
new Token(TokenType.BracketOpen),
new ConstantToken(new IntVariant(0)),
new Token(TokenType.BracketClose),
new Token(TokenType.Colon),
new Token(TokenType.CfReturn),
new Token(TokenType.Newline, 2),
new IdentifierToken("spoken_text"),
new IdentifierToken("final_color"),
new Token(TokenType.OpAssign),
new IdentifierToken("tmp"),
new Token(TokenType.BracketOpen),
@@ -155,656 +342,36 @@ public class LucysNetFixes : IScriptMod {
CodeChange[] changes = {
new CodeChange {
name = "send_message channel 2",
// MESSAGE_ZONE, "zone_owner": PlayerData.player_saved_zone_owner}, "peers", 2)
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
multitoken_prefix = new Func<Token, bool>[] {
t => t is ConstantToken {Value:StringVariant{Value: "instance_actor"}},
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 = []
name = "read packet intercept",
// FLUSH_PACKET_INFORMATION[PACKET_SENDER] += 1
// 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 is IdentifierToken {Name: "FLUSH_PACKET_INFORMATION"},
t => t.Type == TokenType.BracketOpen,
t => t is IdentifierToken {Name: "PACKET_SENDER"},
t => t.Type == TokenType.BracketClose,
t => t.Type == TokenType.OpAssignAdd,
t => t is ConstantToken {Value:IntVariant{Value: 1}},
t => t.Type == TokenType.Newline,
},
// var LUCY_PACKETS_READ = 0
// 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
// if $"/root/LucyLucysTools".process_read(DATA, PACKET_SENDER, from_host): return
// 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[] {
new Token(TokenType.CfIf),
new IdentifierToken("LUCY_SRV_NAME"),
new Token(TokenType.OpEqual),
new ConstantToken(new StringVariant("")),
new Token(TokenType.CfElse),
new IdentifierToken("LUCY_SRV_NAME"),
new Token(TokenType.Dollar),
new ConstantToken(new StringVariant("/root/LucyLucysTools")),
new Token(TokenType.Period),
new IdentifierToken("process_read"),
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.
Client Features:
- Makes the client (tunably) read all packets. This fixes chat messages dropping.
- Optionally knocks people back when they punch you.
- Lets you clear gamechat
- Sends messages on P2P channel 2 (This should make your messages more reliable for users who don't have LucysTools)
- Only the game host can kick/ban you
- Allows custom name bbcode (and/or custom color)
- Allows some BBCode in chat: [b], [i], [u], [s], [color] Make sure to close your tags!
- Allows custom name color (for all users)
- Allows custom name BBCode (for compatible peers)
- Allows custom text color (for compatible peers)
- Allows BBCode in chat (for compatible peers)
- (Bug BBCode) Allows BBCode in chat for everyone to see
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 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, 'raw' messages can be sent with a % prefix
- If intrusive BBCode is enabled, as host 'raw' messages can be sent with a % prefix
Log Features:
- 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.
Info for Modders:
- 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!
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:
- 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)
Bugs: