From 69bd91b2f46dfb3af3f084c2b033511708604522 Mon Sep 17 00:00:00 2001 From: _0Steven <42909981+00-Steven@users.noreply.github.com> Date: Tue, 12 Aug 2025 23:22:35 +0200 Subject: [PATCH] Fixes newscaster channels having a random chance of breaking upon creation of a new channel, refactors how channels are tracked in the first place (#92371) ## About The Pull Request So in a recent round I noticed the newscaster UI was acting kind of funky, where two channels seemed to overlap and weirdly pick between the two in unpredictable ways. Looking into it, it seemed that somehow the channels had managed to get their unique IDs to overlap- Oh. https://github.com/tgstation/tgstation/blob/5d3353e7af2b88ab9379d5fb567b24afd8776acd/code/game/machinery/newscaster/newscaster_data.dm#L109-L131 I see. ...I think that code speaks for itself, in how this could've gone wrong. Anyhow, in this pr we entirely ditch this system, and instead make it use an incremental and thus guaranteed to be unique ID. This fixes our issues. While we're here, we also remove the unused `channel_IDs` list, and replace it with the associative lists `network_channels_by_id` and `network_channels_by_name`. This allows us to also stop iterating over every network channel until we find the one with the right name or ID. We also rename some confusing, wrong, or non-standard vars while we're here. --- code/__HELPERS/roundend.dm | 3 +- code/datums/world_topic.dm | 10 +- .../machinery/newscaster/newscaster_data.dm | 115 ++++++++---------- .../newscaster/newscaster_machine.dm | 69 ++++++----- code/game/machinery/newscaster/newspaper.dm | 4 +- code/modules/admin/verbs/admin_newscaster.dm | 68 ++++++----- code/modules/library/lib_machines.dm | 8 +- .../file_system/programs/betting.dm | 34 ++++-- 8 files changed, 152 insertions(+), 159 deletions(-) diff --git a/code/__HELPERS/roundend.dm b/code/__HELPERS/roundend.dm index 2613edb7acc..59e0b6bd5a6 100644 --- a/code/__HELPERS/roundend.dm +++ b/code/__HELPERS/roundend.dm @@ -158,8 +158,7 @@ GLOBAL_LIST_INIT(achievements_unlocked, list()) var/json_file = file("[GLOB.log_directory]/newscaster.json") var/list/file_data = list() var/pos = 1 - for(var/V in GLOB.news_network.network_channels) - var/datum/feed_channel/channel = V + for(var/datum/feed_channel/channel as anything in GLOB.news_network.network_channels) if(!istype(channel)) stack_trace("Non-channel in newscaster channel list") continue diff --git a/code/datums/world_topic.dm b/code/datums/world_topic.dm index 69989a3f151..346af2651d2 100644 --- a/code/datums/world_topic.dm +++ b/code/datums/world_topic.dm @@ -304,14 +304,8 @@ var/author_key = input["author_ckey"] var/channel_name = input["message"] - var/found_channel = FALSE - for(var/datum/feed_channel/channel as anything in GLOB.news_network.network_channels) - if(channel.channel_name == channel_name) - found_channel = TRUE - break - - // No channel with a matching name, abort - if (!found_channel) + var/datum/feed_channel/chosen_channel = GLOB.news_network.network_channels_by_name[channel_name] + if(isnull(chosen_channel)) // No channel with a matching name, abort return message_admins(span_adminnotice("Incoming cross-sector newscaster article by [author_key] in channel [channel_name].")) diff --git a/code/game/machinery/newscaster/newscaster_data.dm b/code/game/machinery/newscaster/newscaster_data.dm index d67e7e99365..59b8f09db47 100644 --- a/code/game/machinery/newscaster/newscaster_data.dm +++ b/code/game/machinery/newscaster/newscaster_data.dm @@ -42,9 +42,9 @@ GLOBAL_LIST_EMPTY(request_list) ///Referece to the photo used in picture messages. var/photo_file ///What is the channel ID of the parent channel? - var/parent_ID + var/parent_id ///What number message is this? IE: The first message sent in a round including automated messages is message 1. - var/message_ID + var/message_id /datum/feed_message/proc/return_author(censor) if(censor == -1) @@ -99,37 +99,13 @@ GLOBAL_LIST_EMPTY(request_list) var/author_censor /// Is this an admin channel? Allows for actions to be taken by the admin only. var/is_admin_channel = FALSE - /// Channel ID is a random number sequence similar to account ID number that allows for us to link messages to the proper channels through the UI backend. - var/channel_ID + /// Channel ID is a unique number sequence similar to account ID number that allows for us to link messages to the proper channels through the UI backend. + var/channel_id /// Should this channel send cross-server messages? var/cross_sector = FALSE /// Is this a cross-sector channel? If so, this channel can only receive messages via topics var/receiving_cross_sector = FALSE -/datum/feed_channel/New() - . = ..() - channel_ID = random_channel_id_setup() - -/** - * This proc assigns each feed_channel a random integer, from 1-999 as a unique identifier. - * Using this value, the TGUI window has a unique identifier to attach to messages that can be used to reattach them - * to their parent channels back in dreammaker. - * Based on implementation, we're limiting ourselves to only 998 player made channels maximum. How we'd use all of them, I don't know. - */ -/datum/feed_channel/proc/random_channel_id_setup() - if(!GLOB.news_network) - return //Should only apply to channels made before setup is finished, use hardset_channel for these - if(!GLOB.news_network.channel_IDs) - GLOB.news_network.channel_IDs += rand(1,999) - return //This will almost always be the station announcements channel here. - var/channel_id - for(var/i in 1 to 10000) - channel_id = rand(1, 999) - if(!GLOB.news_network.channel_IDs["[channel_ID]"]) - break - channel_ID = channel_id - return channel_ID - /datum/feed_channel/proc/return_author(censor) if(censor == -1) censor = author_censor @@ -173,36 +149,47 @@ GLOBAL_LIST_EMPTY(request_list) /datum/feed_network /// All the feed channels that have been made on the feed network. var/list/datum/feed_channel/network_channels = list() + /// Associative list of all the feed channels that have been made on the feed network, from channel ID to channel. + var/list/datum/feed_channel/network_channels_by_id = list() + /// Associative list of all the feed channels that have been made on the feed network, from channel name to channel. + var/list/datum/feed_channel/network_channels_by_name = list() /// What is the wanted issue being sent out to all newscasters. var/datum/wanted_message/wanted_issue /// What time was the last action taken on the feed_network? var/last_action /// What does this feed network say when a message/author is redacted? var/redacted_text = "\[REDACTED\]" - /// List of all the network_channels Channel Id numbers, kept in a global easy to find place. - var/list/channel_IDs = list() + /// Channel ID to use when next making a new channel, to maintain unique IDs. + var/next_channel_id = 1 /// How many messages currently exist on this feed_network? Increments as new messages are written. var/message_count = 0 /datum/feed_network/New() - create_feed_channel(NEWSCASTER_STATION_ANNOUNCEMENTS, "SS13", "Company news, staff announcements, and all the latest information. Have a secure shift!", locked = TRUE, hardset_channel = 1000) - create_feed_channel(NEWSCASTER_SPACE_BETTING, "NtOS", "News from the SpaceBet PDA App! Download now and make your own bets!", locked = TRUE, hardset_channel = 1001) + create_feed_channel(NEWSCASTER_STATION_ANNOUNCEMENTS, "SS13", "Company news, staff announcements, and all the latest information. Have a secure shift!", locked = TRUE) + create_feed_channel(NEWSCASTER_SPACE_BETTING, "NtOS", "News from the SpaceBet PDA App! Download now and make your own bets!", locked = TRUE) wanted_issue = new /datum/wanted_message -/datum/feed_network/proc/create_feed_channel(channel_name, author, desc, locked, adminChannel = FALSE, hardset_channel = null, author_ckey = null, cross_sector = FALSE, cross_sector_delay = null, receiving_cross_sector = FALSE) - var/datum/feed_channel/newChannel = new /datum/feed_channel - newChannel.channel_name = channel_name - newChannel.author = author - newChannel.channel_desc = desc - newChannel.locked = locked - newChannel.is_admin_channel = adminChannel - newChannel.receiving_cross_sector = receiving_cross_sector - if(hardset_channel) - newChannel.channel_ID = hardset_channel - network_channels += newChannel +/datum/feed_network/proc/add_feed_channel(datum/feed_channel/new_channel) + network_channels += new_channel + network_channels_by_id["[new_channel.channel_id]"] = new_channel + network_channels_by_name["[new_channel.channel_name]"] = new_channel + +/datum/feed_network/proc/create_feed_channel(channel_name, author, desc, locked, adminChannel = FALSE, author_ckey = null, cross_sector = FALSE, cross_sector_delay = null, receiving_cross_sector = FALSE) + var/datum/feed_channel/new_channel = new /datum/feed_channel + new_channel.channel_name = channel_name + new_channel.author = author + new_channel.channel_desc = desc + new_channel.locked = locked + new_channel.is_admin_channel = adminChannel + new_channel.receiving_cross_sector = receiving_cross_sector + new_channel.channel_id = next_channel_id + next_channel_id++ + + add_feed_channel(new_channel) + if(!cross_sector) return - newChannel.cross_sector = TRUE + new_channel.cross_sector = TRUE var/list/payload = list( "author" = author, "author_ckey" = author_ckey, @@ -212,31 +199,32 @@ GLOBAL_LIST_EMPTY(request_list) send2otherserver(html_decode(station_name()), channel_name, "create_news_channel", additional_data = payload) /datum/feed_network/proc/submit_article(msg, author, channel_name, datum/picture/picture, adminMessage = FALSE, allow_comments = TRUE, update_alert = TRUE, mob/author_mob = null) - var/datum/feed_message/newMsg = new /datum/feed_message - newMsg.author = author - newMsg.body = msg - newMsg.time_stamp = "[station_time_timestamp()]" - newMsg.is_admin_message = adminMessage - newMsg.locked = !allow_comments + var/datum/feed_channel/chosen_channel = network_channels_by_name[channel_name] + if(isnull(chosen_channel)) + stack_trace("Article submitted to non-existent newscaster channel: [channel_name]") + return + + var/datum/feed_message/new_article = new /datum/feed_message + new_article.author = author + new_article.body = msg + new_article.time_stamp = "[station_time_timestamp()]" + new_article.is_admin_message = adminMessage + new_article.locked = !allow_comments message_count++ last_action++ - newMsg.creation_time = last_action - newMsg.message_ID = message_count + new_article.creation_time = last_action + new_article.message_id = message_count if(picture) - newMsg.img = picture.picture_image - newMsg.caption = picture.caption - newMsg.photo_file = save_photo(picture.picture_image) + new_article.img = picture.picture_image + new_article.caption = picture.caption + new_article.photo_file = save_photo(picture.picture_image) - for(var/datum/feed_channel/channel in network_channels) - if(channel.channel_name != channel_name) - continue + chosen_channel.messages += new_article + new_article.parent_id = chosen_channel.channel_id - channel.messages += newMsg - newMsg.parent_ID = channel.channel_ID - if (!channel.cross_sector) - break + if(chosen_channel.cross_sector) // Newscaster articles could be huge, and usefulness of first 50 symbols is dubious message_admins(span_adminnotice("Outgoing cross-sector newscaster article by [key_name(author_mob) || author] in channel [channel_name].")) var/list/payload = list( @@ -245,11 +233,10 @@ GLOBAL_LIST_EMPTY(request_list) "msg" = msg, ) send2otherserver(html_decode(station_name()), channel_name, "create_news_article", additional_data = payload) - break for(var/obj/machinery/newscaster/caster in GLOB.allCasters) caster.news_alert(channel_name, update_alert) - return newMsg + return new_article ///Submits a comment on the news network /datum/feed_network/proc/submit_comment(mob/user, comment_text, newscaster_username, datum/feed_message/current_message) diff --git a/code/game/machinery/newscaster/newscaster_machine.dm b/code/game/machinery/newscaster/newscaster_machine.dm index 58e49501e0b..77b9c51d012 100644 --- a/code/game/machinery/newscaster/newscaster_machine.dm +++ b/code/game/machinery/newscaster/newscaster_machine.dm @@ -196,11 +196,11 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30) //Then, breaks down the messages that have been made on those channels. if(current_channel) for(var/datum/feed_message/feed_message as anything in current_channel.messages) - var/photo_ID = null + var/photo_id = null var/list/comment_list if(feed_message.img) - user << browse_rsc(feed_message.img, "tmp_photo[feed_message.message_ID].png") - photo_ID = "tmp_photo[feed_message.message_ID].png" + user << browse_rsc(feed_message.img, "tmp_photo[feed_message.message_id].png") + photo_id = "tmp_photo[feed_message.message_id].png" for(var/datum/feed_comment/comment_message as anything in feed_message.comments) comment_list += list(list( "auth" = comment_message.author, @@ -211,16 +211,16 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30) "auth" = feed_message.author, "body" = feed_message.body, "time" = feed_message.time_stamp, - "channel_num" = feed_message.parent_ID, + "channel_num" = feed_message.parent_id, "censored_message" = feed_message.body_censor, "censored_author" = feed_message.author_censor, - "ID" = feed_message.message_ID, - "photo" = photo_ID, + "ID" = feed_message.message_id, + "photo" = photo_id, "comments" = comment_list )) - data["viewing_channel"] = current_channel?.channel_ID + data["viewing_channel"] = current_channel?.channel_id data["paper"] = paper_remaining //Here we display all the information about the current channel. data["channelName"] = current_channel?.channel_name @@ -264,7 +264,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30) "author" = channel.author, "censored" = channel.censored, "locked" = channel.locked, - "ID" = channel.channel_ID, + "ID" = channel.channel_id, )) data["channels"] = channel_list @@ -293,19 +293,20 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30) switch(action) if("setChannel") - var/prototype_channel = params["channel"] - if(isnull(prototype_channel)) + var/selected_channel_id = params["channel"] + if(isnull(selected_channel_id)) return TRUE - for(var/datum/feed_channel/potential_channel as anything in GLOB.news_network.network_channels) - if(prototype_channel == potential_channel.channel_ID) - current_channel = potential_channel + var/datum/feed_channel/potential_channel = GLOB.news_network.network_channels_by_id["[selected_channel_id]"] + if(isnull(potential_channel)) + return TRUE + current_channel = potential_channel if("createStory") if(!current_channel) balloon_alert(user, "select a channel first!") return TRUE - var/prototype_channel = params["current"] - create_story(user, channel_name = prototype_channel) + var/current_channel_id = params["current"] + create_story(user, channel_id = current_channel_id) if("togglePhoto") toggle_photo(user) @@ -352,7 +353,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30) return TRUE var/questionable_message = params["messageID"] for(var/datum/feed_message/iterated_feed_message as anything in current_channel.messages) - if(iterated_feed_message.message_ID == questionable_message) + if(iterated_feed_message.message_id == questionable_message) iterated_feed_message.toggle_censor_body() break @@ -366,7 +367,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30) return TRUE var/questionable_message = params["messageID"] for(var/datum/feed_message/iterated_feed_message in current_channel.messages) - if(iterated_feed_message.message_ID == questionable_message) + if(iterated_feed_message.message_id == questionable_message) iterated_feed_message.toggle_censor_author() break @@ -378,11 +379,13 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30) if(!(admin_access in id_card?.GetAccess())) say("Clearance not found.") return TRUE - var/prototype_channel = (params["channel"]) - for(var/datum/feed_channel/potential_channel in GLOB.news_network.network_channels) - if(prototype_channel == potential_channel.channel_ID) - current_channel = potential_channel - break + var/selected_channel_id = (params["channel"]) + if(isnull(selected_channel_id)) + return TRUE + var/datum/feed_channel/potential_channel = GLOB.news_network.network_channels_by_id["[selected_channel_id]"] + if(isnull(potential_channel)) + return TRUE + current_channel = potential_channel current_channel.toggle_censor_D_class() if("startComment") @@ -394,7 +397,7 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30) if(!commentable_message) return TRUE for(var/datum/feed_message/iterated_feed_message as anything in current_channel.messages) - if(iterated_feed_message.message_ID == commentable_message) + if(iterated_feed_message.message_id == commentable_message) current_message = iterated_feed_message return TRUE @@ -660,10 +663,10 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30) if(isnull(channel_locked)) return TRUE - for(var/datum/feed_channel/iterated_feed_channel as anything in GLOB.news_network.network_channels) - if(iterated_feed_channel.channel_name == channel_name) - tgui_alert(user, "ERROR: Feed channel with that name already exists on the Network.", list("Okay")) - return TRUE + var/datum/feed_channel/potential_channel = GLOB.news_network.network_channels_by_name[channel_name] + if(potential_channel) + tgui_alert(user, "ERROR: Feed channel with that name already exists on the Network.", list("Okay")) + return TRUE var/list/hard_filter_result = is_ic_filtered(channel_name) if(hard_filter_result) @@ -769,13 +772,13 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/machinery/newscaster, 30) * Verifies that the message is being written to a real feed_channel, then provides a text input for the feed story to be written into. * Finally, it submits the message to the network, is logged globally, and clears all message-specific variables from the machine. */ -/obj/machinery/newscaster/proc/create_story(mob/user, channel_name) - for(var/datum/feed_channel/potential_channel as anything in GLOB.news_network.network_channels) - if(channel_name == potential_channel.channel_ID) - current_channel = potential_channel - break +/obj/machinery/newscaster/proc/create_story(mob/user, channel_id) + var/datum/feed_channel/potential_channel = GLOB.news_network.network_channels_by_id["[channel_id]"] + if(isnull(potential_channel)) + return + current_channel = potential_channel - if (current_channel.receiving_cross_sector) + if(current_channel.receiving_cross_sector) return var/temp_message = tgui_input_text(user, "Write your Feed story", "Network Channel Handler", feed_channel_message, max_length = MAX_BROADCAST_LEN, multiline = TRUE) diff --git a/code/game/machinery/newscaster/newspaper.dm b/code/game/machinery/newscaster/newspaper.dm index 88946a89b5a..de706f1b5f5 100644 --- a/code/game/machinery/newscaster/newspaper.dm +++ b/code/game/machinery/newscaster/newspaper.dm @@ -268,10 +268,10 @@ var/has_image = FALSE if(feed_messages.img) has_image = TRUE - user << browse_rsc(feed_messages.img, "tmp_photo[feed_messages.message_ID].png") + user << browse_rsc(feed_messages.img, "tmp_photo[feed_messages.message_id].png") channel_data["channel_messages"] += list(list( "message" = "-[feed_messages.return_body(censored_check(feed_messages.body_censor_time))]", - "photo" = (has_image ? "tmp_photo[feed_messages.message_ID].png" : null), + "photo" = (has_image ? "tmp_photo[feed_messages.message_id].png" : null), "author" = feed_messages.return_author(censored_check(feed_messages.author_censor_time)), )) data["channel_data"] = list(channel_data) diff --git a/code/modules/admin/verbs/admin_newscaster.dm b/code/modules/admin/verbs/admin_newscaster.dm index d199d31e9b9..e300150659b 100644 --- a/code/modules/admin/verbs/admin_newscaster.dm +++ b/code/modules/admin/verbs/admin_newscaster.dm @@ -86,15 +86,15 @@ ADMIN_VERB(access_news_network, R_ADMIN, "Access Newscaster Network", "Allows yo "author" = channel.author, "censored" = channel.censored, "locked" = channel.locked, - "ID" = channel.channel_ID, + "ID" = channel.channel_id, )) if(current_channel) for(var/datum/feed_message/feed_message as anything in current_channel.messages) - var/photo_ID = null + var/photo_id = null var/list/comment_list if(feed_message.img) - user << browse_rsc(feed_message.img, "tmp_photo[feed_message.message_ID].png") - photo_ID = "tmp_photo[feed_message.message_ID].png" + user << browse_rsc(feed_message.img, "tmp_photo[feed_message.message_id].png") + photo_id = "tmp_photo[feed_message.message_id].png" for(var/datum/feed_comment/comment_message as anything in feed_message.comments) comment_list += list(list( "auth" = comment_message.author, @@ -105,16 +105,16 @@ ADMIN_VERB(access_news_network, R_ADMIN, "Access Newscaster Network", "Allows yo "auth" = feed_message.author, "body" = feed_message.body, "time" = feed_message.time_stamp, - "channel_num" = feed_message.parent_ID, + "channel_num" = feed_message.parent_id, "censored_message" = feed_message.body_censor, "censored_author" = feed_message.author_censor, - "ID" = feed_message.message_ID, - "photo" = photo_ID, + "ID" = feed_message.message_id, + "photo" = photo_id, "comments" = comment_list )) - data["viewing_channel"] = current_channel?.channel_ID + data["viewing_channel"] = current_channel?.channel_id //Here we display all the information about the current channel. data["channelName"] = current_channel?.channel_name data["channelAuthor"] = current_channel?.author @@ -141,19 +141,20 @@ ADMIN_VERB(access_news_network, R_ADMIN, "Access Newscaster Network", "Allows yo switch(action) if("setChannel") - var/prototype_channel = params["channel"] - if(isnull(prototype_channel)) + var/selected_channel_id = params["channel"] + if(isnull(selected_channel_id)) return TRUE - for(var/datum/feed_channel/potential_channel as anything in GLOB.news_network.network_channels) - if(prototype_channel == potential_channel.channel_ID) - current_channel = potential_channel + var/datum/feed_channel/potential_channel = GLOB.news_network.network_channels_by_id["[selected_channel_id]"] + if(isnull(potential_channel)) + return TRUE + current_channel = potential_channel if("createStory") if(!current_channel) to_chat(usr, "select a channel first!") return TRUE - var/prototype_channel = params["current"] - create_story(channel_name = prototype_channel) + var/current_channel_id = params["current"] + create_story(channel_id = current_channel_id) if("togglePhoto") toggle_photo() @@ -189,23 +190,25 @@ ADMIN_VERB(access_news_network, R_ADMIN, "Access Newscaster Network", "Allows yo if("storyCensor") var/questionable_message = params["messageID"] for(var/datum/feed_message/iterated_feed_message as anything in current_channel.messages) - if(iterated_feed_message.message_ID == questionable_message) + if(iterated_feed_message.message_id == questionable_message) iterated_feed_message.toggle_censor_body() break if("author_censor") var/questionable_message = params["messageID"] for(var/datum/feed_message/iterated_feed_message in current_channel.messages) - if(iterated_feed_message.message_ID == questionable_message) + if(iterated_feed_message.message_id == questionable_message) iterated_feed_message.toggle_censor_author() break if("channelDNotice") - var/prototype_channel = (params["channel"]) - for(var/datum/feed_channel/potential_channel in GLOB.news_network.network_channels) - if(prototype_channel == potential_channel.channel_ID) - current_channel = potential_channel - break + var/selected_channel_id = (params["channel"]) + if(isnull(selected_channel_id)) + return TRUE + var/datum/feed_channel/potential_channel = GLOB.news_network.network_channels_by_id["[selected_channel_id]"] + if(isnull(potential_channel)) + return TRUE + current_channel = potential_channel current_channel.toggle_censor_D_class() if("startComment") @@ -214,7 +217,7 @@ ADMIN_VERB(access_news_network, R_ADMIN, "Access Newscaster Network", "Allows yo if(!commentable_message) return TRUE for(var/datum/feed_message/iterated_feed_message as anything in current_channel.messages) - if(iterated_feed_message.message_ID == commentable_message) + if(iterated_feed_message.message_id == commentable_message) current_message = iterated_feed_message return TRUE @@ -284,10 +287,10 @@ ADMIN_VERB(access_news_network, R_ADMIN, "Access Newscaster Network", "Allows yo /datum/newspanel/proc/create_channel(channel_locked) if(!channel_name) return - for(var/datum/feed_channel/iterated_feed_channel as anything in GLOB.news_network.network_channels) - if(iterated_feed_channel.channel_name == channel_name) - tgui_alert(usr, "ERROR: Feed channel with that name already exists on the Network.", list("Okay")) - return TRUE + var/datum/feed_channel/potential_channel = GLOB.news_network.network_channels_by_name[channel_name] + if(potential_channel) + tgui_alert(usr, "ERROR: Feed channel with that name already exists on the Network.", list("Okay")) + return TRUE if(!channel_desc) return TRUE if(isnull(channel_locked)) @@ -334,11 +337,12 @@ ADMIN_VERB(access_news_network, R_ADMIN, "Access Newscaster Network", "Allows yo * Verifies that the message is being written to a real feed_channel, then provides a text input for the feed story to be written into. * Finally, it submits the message to the network, is logged globally, and clears all message-specific variables from the machine. */ -/datum/newspanel/proc/create_story(channel_name) - for(var/datum/feed_channel/potential_channel as anything in GLOB.news_network.network_channels) - if(channel_name == potential_channel.channel_ID) - current_channel = potential_channel - break +/datum/newspanel/proc/create_story(channel_id) + var/datum/feed_channel/potential_channel = GLOB.news_network.network_channels_by_id["[channel_id]"] + if(isnull(potential_channel)) + return + current_channel = potential_channel + var/temp_message = tgui_input_text(usr, "Write your Feed story", "Network Channel Handler", feed_channel_message, max_length = MAX_BROADCAST_LEN, multiline = TRUE) if(length(temp_message) <= 1) return TRUE diff --git a/code/modules/library/lib_machines.dm b/code/modules/library/lib_machines.dm index edf77d4873e..62266481659 100644 --- a/code/modules/library/lib_machines.dm +++ b/code/modules/library/lib_machines.dm @@ -507,12 +507,8 @@ GLOBAL_VAR_INIT(library_table_modified, 0) return if(!GLOB.news_network) say("No news network found on station. Aborting.") - var/channelexists = FALSE - for(var/datum/feed_channel/feed in GLOB.news_network.network_channels) - if(feed.channel_name == LIBRARY_NEWSFEED) - channelexists = TRUE - break - if(!channelexists) + var/datum/feed_channel/library_channel = GLOB.news_network.network_channels_by_name[LIBRARY_NEWSFEED] + if(isnull(library_channel)) GLOB.news_network.create_feed_channel(LIBRARY_NEWSFEED, "Library", "The official station book club!", null) var/obj/machinery/libraryscanner/scan = get_scanner() diff --git a/code/modules/modular_computers/file_system/programs/betting.dm b/code/modules/modular_computers/file_system/programs/betting.dm index 01a13761667..d368d15e8e7 100644 --- a/code/modules/modular_computers/file_system/programs/betting.dm +++ b/code/modules/modular_computers/file_system/programs/betting.dm @@ -170,19 +170,32 @@ GLOBAL_LIST_EMPTY_TYPED(active_bets, /datum/active_bet) for(var/option in options) if(!length(options[option])) options[option] = list() - //we'll only advertise it on the first bet of the round, as to not make this overly annoying. - var/should_alert = FALSE - for(var/datum/feed_channel/FC in GLOB.news_network.network_channels) - if(FC.channel_name == NEWSCASTER_SPACE_BETTING) - if(!length(FC.messages)) - should_alert = TRUE - newscaster_message = GLOB.news_network.submit_article("The bet [name] has started, place your bets now!", "NtOS Space Betting App", NEWSCASTER_SPACE_BETTING, null, update_alert = should_alert) + advertise_bet() /datum/active_bet/Destroy(force) GLOB.active_bets -= src newscaster_message = null return ..() +/// Place a feed article advertising our bet. +/datum/active_bet/proc/advertise_bet() + var/datum/feed_channel/betting_channel = GLOB.news_network.network_channels_by_name[NEWSCASTER_SPACE_BETTING] + if(isnull(betting_channel)) + return + // We'll only advertise it on the first bet of the round, as to not make this overly annoying. + var/should_alert = !length(betting_channel.messages) + newscaster_message = GLOB.news_network.submit_article("The bet [name] has started, place your bets now!", "NtOS Space Betting App", NEWSCASTER_SPACE_BETTING, null, update_alert = should_alert) + +/// Reply to our previously placed advertisement feed article. +/datum/active_bet/proc/reply_to_feed(winning_option) + if(isnull(newscaster_message)) + return + GLOB.news_network.submit_comment( + comment_text = "The bet [name] has ended, the winner was [winning_option]!", + newscaster_username = "NtOS Betting Results", + current_message = newscaster_message, + ) + ///Returns how many bets there is per option /datum/active_bet/proc/get_bets(datum/bank_account/user_account) var/list/bets_per_option = list() @@ -206,11 +219,8 @@ GLOBAL_LIST_EMPTY_TYPED(active_bets, /datum/active_bet) var/datum/bank_account/refunded_account = existing_bets[1] refunded_account.adjust_money(text2num(existing_bets[2]), "Refund: [name] gamble cancelled.") return - GLOB.news_network.submit_comment( - comment_text = "The bet [name] has ended, the winner was [winning_option]!", - newscaster_username = "NtOS Betting Results", - current_message = newscaster_message, - ) + + reply_to_feed(winning_option) var/list/winners = options[winning_option] if(!length(winners)) return