139 lines
5.2 KiB
GDScript
139 lines
5.2 KiB
GDScript
@tool
|
|
extends Control
|
|
class_name ChatBox
|
|
|
|
enum ChatDock { BOTTOM, LEFT, TOP, RIGHT }
|
|
@onready var chat_history: ScrollContainer = %ChatHistory
|
|
@onready var history: VBoxContainer = %History
|
|
@onready var height: int = 250
|
|
@onready var width: int = 200
|
|
|
|
@export var dock: ChatDock = ChatDock.BOTTOM:
|
|
set(value):
|
|
dock = value
|
|
if not is_node_ready(): return
|
|
_orientate_chatbox()
|
|
|
|
func _ready() -> void:
|
|
var waiting_for_ready := false
|
|
if Engine.is_editor_hint():
|
|
return
|
|
while Globals.twitcher == null or !Globals.twitcher.is_node_ready():
|
|
if not waiting_for_ready:
|
|
print("Waiting for Twitcher Ready...")
|
|
waiting_for_ready = true
|
|
await get_tree().process_frame
|
|
print("Twitcher ready!")
|
|
_orientate_chatbox()
|
|
|
|
Globals.twitcher.chat.message_received.connect(_handle_chat)
|
|
|
|
func _orientate_chatbox() -> void:
|
|
match dock:
|
|
ChatDock.BOTTOM:
|
|
chat_history.custom_minimum_size = Vector2(1550,265)
|
|
chat_history.size = Vector2(1550,265)
|
|
chat_history.position = Vector2(0, get_viewport_rect().size.y - 265)
|
|
#chat_history.set_anchors_preset(Control.PRESET_BOTTOM_WIDE)
|
|
#chat_history.custom_minimum_size = Vector2(0,height)
|
|
ChatDock.LEFT:
|
|
chat_history.custom_minimum_size = Vector2(500,get_viewport_rect().size.y)
|
|
chat_history.size = Vector2(500,get_viewport_rect().size.y)
|
|
chat_history.position = Vector2.ZERO
|
|
#chat_history.set_anchors_preset(Control.PRESET_LEFT_WIDE)
|
|
#chat_history.custom_minimum_size = Vector2(width,0)
|
|
ChatDock.RIGHT:
|
|
chat_history.custom_minimum_size = Vector2(500, get_viewport_rect().size.y - 265)
|
|
chat_history.size = Vector2(500, 265)
|
|
chat_history.position = Vector2(get_viewport_rect().size.x - 500, 0)
|
|
#chat_history.set_anchors_preset(Control.PRESET_RIGHT_WIDE)
|
|
#chat_history.custom_minimum_size = Vector2(width,0)
|
|
ChatDock.TOP:
|
|
chat_history.custom_minimum_size = Vector2(1550,265)
|
|
chat_history.size = Vector2(1550,265)
|
|
chat_history.position = Vector2.ZERO
|
|
#chat_history.set_anchors_preset(Control.PRESET_TOP_WIDE)
|
|
#chat_history.custom_minimum_size = Vector2(0,height)
|
|
|
|
func _handle_chat(message: TwitchChatMessage) -> void:
|
|
var badges_dict: Dictionary = await message.get_badges(Globals.twitcher.media)
|
|
var badges: Array[SpriteFrames] = []
|
|
badges.assign(badges_dict.values())
|
|
|
|
var result_message: String = ""
|
|
var badge_id: int = 0
|
|
for badge: SpriteFrames in badges:
|
|
result_message += "[sprite id='b-%s']%s[/sprite]" % [badge_id, badge.resource_path]
|
|
badge_id += 1
|
|
result_message += "[color=%s]%s[/color]" % [message.get_color(), message.chatter_user_name]
|
|
|
|
match message.message_type:
|
|
TwitchChatMessage.MessageType.text:
|
|
result_message = await show_text(message, result_message)
|
|
|
|
TwitchChatMessage.MessageType.power_ups_gigantified_emote:
|
|
result_message = await show_text(message, result_message, 3)
|
|
|
|
TwitchChatMessage.MessageType.channel_points_highlighted:
|
|
result_message += "[bgcolor=#755ebc][color=#e9fffb]"
|
|
result_message = await show_text(message, result_message)
|
|
result_message += "[/color][/bgcolor]"
|
|
|
|
TwitchChatMessage.MessageType.power_ups_message_effect:
|
|
result_message += "[shake rate=20.0 level=5 connected=1]"
|
|
result_message = await show_text(message, result_message)
|
|
result_message += "[/shake]"
|
|
|
|
append_message(result_message)
|
|
|
|
func show_text(message: TwitchChatMessage, current_text: String, emote_scale: int = 1) -> String:
|
|
await message.load_emotes_from_fragment(Globals.twitcher.media)
|
|
var frag_id: int = 0
|
|
for fragment: TwitchChatMessage.Fragment in message.message.fragments:
|
|
frag_id += 1
|
|
match fragment.type:
|
|
TwitchChatMessage.FragmentType.text:
|
|
current_text += fragment.text
|
|
TwitchChatMessage.FragmentType.cheermote:
|
|
var cheermote_scale: StringName = TwitchCheermoteDefinition.SCALE_MAP.get(emote_scale, TwitchCheermoteDefinition.SCALE_1)
|
|
var cheermote: SpriteFrames = await fragment.cheermote.get_sprite_frames(Globals.twitcher.media, cheermote_scale)
|
|
current_text += "[sprite id='f-%s']%s[/sprite]" % [frag_id, cheermote.resource_path]
|
|
TwitchChatMessage.FragmentType.emote:
|
|
var emote: SpriteFrames = await fragment.emote.get_sprite_frames(Globals.twitcher.media, emote_scale)
|
|
current_text += "[sprite id='f-%s']%s[/sprite]" % [frag_id, emote.resource_path]
|
|
TwitchChatMessage.FragmentType.mention:
|
|
current_text += "[color=%s]@%s[/color]" % ["%00a0b6", fragment.mention.user_name]
|
|
return current_text
|
|
|
|
func append_message(msg: String) -> void:
|
|
var cm: RichTextLabel = RichTextLabel.new()
|
|
cm.bbcode_enabled = true
|
|
cm.fit_content = true
|
|
|
|
var se: SpriteFrameEffect = SpriteFrameEffect.new()
|
|
cm.install_effect(se)
|
|
%History.add_child(cm)
|
|
|
|
msg = se.prepare_message(msg, cm)
|
|
cm.text = _get_time() + " " + msg
|
|
|
|
_clean_old_messages()
|
|
|
|
await get_tree().process_frame
|
|
var rect = cm.get_rect()
|
|
%ChatHistory.set_deferred("scroll_vertical",rect.position.y + rect.size.y)
|
|
|
|
func _clean_old_messages() -> void:
|
|
var child_count := %ChatHistory.get_child_count()
|
|
if child_count < 1000: return
|
|
for i in child_count - 1000:
|
|
%ChatHistory.get_child(i).queue_free()
|
|
|
|
func _get_time() -> String:
|
|
var time: Dictionary = Time.get_time_dict_from_system()
|
|
var pm := false
|
|
if time["hour"] >= 12:
|
|
pm = true
|
|
if time["hour"] > 12:
|
|
time["hour"] -= 12
|
|
return "%02d:%02d%s" % [time["hour"], time["minute"], "PM" if pm else "AM"]
|