You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 lines
3.3 KiB

extends BaseEmotesCache
class_name FfzEmotesCache
signal emote_retrieved(emote)
class FfzEmote:
var id: String
var code: String
var texture: ImageTexture
func _init(id: String, code: String, image: Image):
self.id = id
self.code = code
self.texture = BaseEmotesCache.BaseEmote.create_texture_from_image(image)
const DEFAULT_URL_PROTOCOL = 'https://'
const USER_ID_PLACEHOLDER = '{{user_id}}'
const EMOTE_ID_PLACEHOLDER = '{{id}}'
const EMOTE_SIZE_PLACEHOLDER = '{{image}}'
# Can be: 1x, 2x, 3x
const DEAFULT_EMOTE_IMAGE_SIZE = '1x'
const GLOBAL_EMOTES_REQUEST_ID = 'global_emotes'
const CHANNEL_EMOTES_REQUEST_ID = 'channel_emotes'
const EMOTES_REQUEST_IDS = [GLOBAL_EMOTES_REQUEST_ID, CHANNEL_EMOTES_REQUEST_ID]
const GLOBAL_EMOTES_URL = 'https://api.frankerfacez.com/v1/set/global'
const CHANNEL_EMOTES_URL_TEMPLATE = 'https://api.frankerfacez.com/v1/room/id/{{user_id}}'
# {
# "code": {
# "id": "",
# "url": ""
# }
# }
# code -- text to replace
# id -- internal ffz emote id
# url -- direct image url
var available_emotes := Dictionary()
var cache := Dictionary()
var available_emotes_parsed_count := 0
var user_id: String
# hooks
func _downloaded(downloaded_content: BaseEmotesCache.DownloadedContent) -> void:
if downloaded_content.id in EMOTES_REQUEST_IDS:
__parse_available_emotes(downloaded_content)
available_emotes_parsed_count += 1
ready_to_deliver_emotes = available_emotes_parsed_count >= EMOTES_REQUEST_IDS.size()
else:
var code: String = str(downloaded_content.id)
var id: String = available_emotes.get(code, {}).get('id')
var image: Image = downloaded_content.get_image_from_data()
cache[code] = FfzEmote.new(id, code, image)
emit_signal("emote_retrieved", cache.get(code))
func _get_emote_url(code: String) -> String:
var url: String = available_emotes.get(code, {}).get('url', '')
return url
# public
func init_emotes(user_id: String, force: bool=false) -> void:
if self.user_id == null or self.user_id != user_id or force:
user_id = user_id
http_request_queue.enqueue_request(GLOBAL_EMOTES_REQUEST_ID, GLOBAL_EMOTES_URL)
http_request_queue.enqueue_request(
CHANNEL_EMOTES_REQUEST_ID,
CHANNEL_EMOTES_URL_TEMPLATE.replace(USER_ID_PLACEHOLDER, user_id)
)
# public
func get_emote(code: String) -> void:
if not ready_to_deliver_emotes:
return
if cache.has(code):
emit_signal("emote_retrieved", cache.get(code))
else:
__cache_emote(code)
func get_available_emotes_codes() -> Array:
return available_emotes.keys()
# private
func __parse_available_emotes(download_content: BaseEmotesCache.DownloadedContent) -> void:
if download_content.type != HttpHeaders.HTTP_CONTENT_TYPE_JSON:
return
var data = parse_json(download_content.data.get_string_from_utf8())
var sets := data.get('sets') as Dictionary
for set in sets.values():
var emotes := set.get('emoticons') as Array
for emote in emotes:
var emote_url: String = emote.get('urls', {}).get('1', '').replace(
'//', DEFAULT_URL_PROTOCOL
)
var id := str(emote.get('id'), '')
available_emotes[emote.get('name')] = {
'id': id,
'url': emote_url
}