diff --git a/Content.Server/_Sunrise/Messenger/MessengerServerSystem.Messages.cs b/Content.Server/_Sunrise/Messenger/MessengerServerSystem.Messages.cs
index 9773b548b9..f17ca3ed82 100644
--- a/Content.Server/_Sunrise/Messenger/MessengerServerSystem.Messages.cs
+++ b/Content.Server/_Sunrise/Messenger/MessengerServerSystem.Messages.cs
@@ -401,4 +401,79 @@ public sealed partial class MessengerServerSystem
}
}
}
+ ///
+ /// Sends a fake message to a specific user (used for spam).
+ ///
+ public void SendFakePersonalMessage(EntityUid uid, string recipientId, string senderId, string senderName, string content)
+ {
+ if (!TryComp(uid, out var component))
+ return;
+
+ if (!component.Users.ContainsKey(recipientId))
+ return;
+
+ var timestamp = GetStationTime();
+ var messageId = GetNextMessageId(uid, component);
+ var message = new MessengerMessage(senderId, senderName, content, timestamp, null, recipientId, isRead: false, messageId);
+ var chatId = GetPersonalChatId(senderId, recipientId);
+
+ if (!component.MessageHistory.TryGetValue(chatId, out var history))
+ {
+ history = new List();
+ component.MessageHistory[chatId] = history;
+ }
+
+ history.Add(message);
+ TrimMessageHistory(history, component.MaxMessageHistory);
+
+ var isChatOpen = component.OpenChats.TryGetValue(recipientId, out var openChatId) && openChatId == chatId;
+
+ if (isChatOpen)
+ {
+ message.IsRead = true;
+ }
+ else
+ {
+ if (!component.UnreadCounts.TryGetValue(recipientId, out var recipientUnreads))
+ {
+ recipientUnreads = new Dictionary();
+ component.UnreadCounts[recipientId] = recipientUnreads;
+ }
+ recipientUnreads.TryGetValue(chatId, out var currentCount);
+ recipientUnreads[chatId] = currentCount + 1;
+ }
+
+ if (!TryComp(uid, out var serverDevice))
+ return;
+
+ uint? pdaFrequency = null;
+ if (_prototypeManager.TryIndex(component.PdaFrequencyId, out var pdaFreq))
+ {
+ pdaFrequency = pdaFreq.Frequency;
+ }
+
+ var payload = new NetworkPayload
+ {
+ [DeviceNetworkConstants.Command] = MessengerCommands.CmdMessageReceived,
+ ["sender_id"] = message.SenderId,
+ ["sender_name"] = message.SenderName,
+ ["content"] = message.Content,
+ ["timestamp"] = message.Timestamp.TotalSeconds,
+ ["group_id"] = message.GroupId ?? string.Empty,
+ ["recipient_id"] = message.RecipientId ?? string.Empty,
+ ["is_read"] = message.IsRead,
+ ["message_id"] = message.MessageId,
+ ["sender_job_icon_id"] = string.Empty,
+ ["image_path"] = string.Empty
+ };
+
+ if (pdaFrequency.HasValue)
+ {
+ _deviceNetwork.QueuePacket(uid, recipientId, payload, frequency: pdaFrequency, network: serverDevice.DeviceNetId);
+ }
+ else
+ {
+ _deviceNetwork.QueuePacket(uid, recipientId, payload);
+ }
+ }
}
diff --git a/Content.Server/_Sunrise/Messenger/MessengerServerSystem.Spam.cs b/Content.Server/_Sunrise/Messenger/MessengerServerSystem.Spam.cs
new file mode 100644
index 0000000000..4c15d7d483
--- /dev/null
+++ b/Content.Server/_Sunrise/Messenger/MessengerServerSystem.Spam.cs
@@ -0,0 +1,181 @@
+using System.Linq;
+using Content.Shared._Sunrise.Messenger;
+using Content.Shared._Sunrise.SunriseCCVars;
+using Content.Shared.Dataset;
+using Robust.Shared.Configuration;
+using Robust.Shared.Random;
+using Robust.Shared.Timing;
+
+namespace Content.Server._Sunrise.Messenger;
+
+public sealed partial class MessengerServerSystem
+{
+ [Dependency] private readonly IConfigurationManager _cfg = default!;
+ [Dependency] private readonly IGameTiming _timing = default!;
+
+ private bool _spamEnabled;
+ private float _spamMinTime;
+ private float _spamMaxTime;
+ private float _spamPlayerPercentage;
+
+ private TimeSpan _nextTick = TimeSpan.Zero;
+ private readonly TimeSpan _refreshCooldown = TimeSpan.FromSeconds(1);
+
+ private void InitializeSpam()
+ {
+ Subs.CVar(_cfg, SunriseCCVars.MessengerSpamEnabled, OnSpamEnabledChanged, true);
+ Subs.CVar(_cfg, SunriseCCVars.MessengerSpamMinTime, OnSpamMinTimeChanged, true);
+ Subs.CVar(_cfg, SunriseCCVars.MessengerSpamMaxTime, OnSpamMaxTimeChanged, true);
+ Subs.CVar(_cfg, SunriseCCVars.MessengerSpamPlayerPercentage, OnSpamPlayerPercentageChanged, true);
+ }
+
+ private void OnSpamEnabledChanged(bool value)
+ {
+ _spamEnabled = value;
+ }
+
+ private void OnSpamMinTimeChanged(float value)
+ {
+ UpdateSpamTiming(value, _spamMaxTime);
+ }
+
+ private void OnSpamMaxTimeChanged(float value)
+ {
+ UpdateSpamTiming(_spamMinTime, value);
+ }
+
+ private void OnSpamPlayerPercentageChanged(float value)
+ {
+ _spamPlayerPercentage = value;
+ }
+
+ private void UpdateSpamTiming(float min, float max)
+ {
+ _spamMinTime = min;
+ _spamMaxTime = max;
+
+ if (_spamMinTime > _spamMaxTime)
+ {
+ (_spamMinTime, _spamMaxTime) = (_spamMaxTime, _spamMinTime);
+ }
+ }
+
+ private void ResetSpamTimer(StationMessengerSpamComponent component)
+ {
+ component.Timer = 0;
+ component.NextSpamTime = _random.NextFloat(_spamMinTime, _spamMaxTime);
+ }
+
+ private void UpdateSpam(float frameTime)
+ {
+ if (_nextTick > _timing.CurTime)
+ return;
+
+ _nextTick = _timing.CurTime + _refreshCooldown;
+
+ if (!_spamEnabled)
+ return;
+
+ var query = EntityQueryEnumerator();
+ while (query.MoveNext(out var uid, out var spam))
+ {
+ if (spam.NextSpamTime <= 0)
+ {
+ ResetSpamTimer(spam);
+ continue;
+ }
+
+ spam.Timer += (float)_refreshCooldown.TotalSeconds;
+
+ if (spam.Timer < spam.NextSpamTime)
+ continue;
+
+ ResetSpamTimer(spam);
+
+ var serverResult = GetServerEntity(uid);
+ if (serverResult != null)
+ {
+ Sawmill.Info($"Triggering spam wave for station {uid} (Server: {serverResult.Value.Item1})");
+ SendSpamWave(serverResult.Value.Item1, serverResult.Value.Item2);
+ }
+ else
+ {
+ Sawmill.Warning($"Could not find messenger server for station {uid}, skipping spam wave.");
+ }
+ }
+ }
+
+ private void SendSpamWave(EntityUid uid, MessengerServerComponent component)
+ {
+ var prototypes = _prototypeManager.EnumeratePrototypes().ToList();
+ if (prototypes.Count == 0)
+ return;
+
+ var players = new List<(EntityUid Uid, MessengerServerComponent Component, MessengerUser User)>();
+
+ foreach (var user in component.Users.Values)
+ {
+ // Skip spam bots
+ if (user.UserId.StartsWith("spam_"))
+ continue;
+
+ players.Add((uid, component, user));
+ }
+
+ if (players.Count == 0)
+ {
+ return;
+ }
+
+ var targetCount = (int)(players.Count * _spamPlayerPercentage);
+ if (targetCount < 1)
+ targetCount = 1;
+
+ _random.Shuffle(players);
+
+ var count = Math.Min(targetCount, players.Count);
+
+ Sawmill.Info($"Sending spam to {count} users (Total: {players.Count}, Target %: {_spamPlayerPercentage})");
+
+ for (int i = 0; i < count; i++)
+ {
+ var p = players[i];
+ SendSpamToUser(p.Uid, p.Component, p.User, prototypes);
+ }
+ }
+
+ private void SendSpamToUser(EntityUid uid, MessengerServerComponent component, MessengerUser user, List prototypes)
+ {
+ var proto = _random.Pick(prototypes);
+
+ var senderName = GetRandomString(proto.SenderDataset);
+ if (proto.NameDataset != null && proto.SurnameDataset != null)
+ {
+ senderName += " " + GetRandomString(proto.NameDataset);
+ senderName += " " + GetRandomString(proto.SurnameDataset);
+ }
+
+ var messageContent = GetRandomString(proto.MessageDataset);
+ if (string.IsNullOrWhiteSpace(messageContent))
+ return;
+
+ var senderId = $"spam_{Math.Abs(senderName.GetHashCode())}";
+
+ if (!component.Users.ContainsKey(senderId))
+ {
+ var spamUser = new MessengerUser(senderId, senderName);
+ component.Users.Add(senderId, spamUser);
+ }
+
+ SendFakePersonalMessage(uid, user.UserId, senderId, senderName, messageContent);
+ }
+
+ private string GetRandomString(string datasetId)
+ {
+ if (!_prototypeManager.TryIndex(datasetId, out LocalizedDatasetPrototype? dataset))
+ return "Error";
+
+ var key = _random.Pick(dataset.Values);
+ return _loc.GetString(key);
+ }
+}
diff --git a/Content.Server/_Sunrise/Messenger/MessengerServerSystem.cs b/Content.Server/_Sunrise/Messenger/MessengerServerSystem.cs
index 48e3f774ad..8fbd1e8594 100644
--- a/Content.Server/_Sunrise/Messenger/MessengerServerSystem.cs
+++ b/Content.Server/_Sunrise/Messenger/MessengerServerSystem.cs
@@ -11,6 +11,7 @@ using Content.Shared.Inventory;
using Robust.Shared.Prototypes;
using Content.Server.CartridgeLoader;
using Content.Server.DeviceNetwork.Components;
+using Robust.Shared.Random;
namespace Content.Server._Sunrise.Messenger;
@@ -27,7 +28,7 @@ public sealed partial class MessengerServerSystem : EntitySystem
[Dependency] private readonly ILocalizationManager _loc = default!;
[Dependency] private readonly InventorySystem _inventory = default!;
[Dependency] private readonly CartridgeLoaderSystem _cartridgeLoader = default!;
-
+ [Dependency] private readonly IRobustRandom _random = default!;
private ISawmill Sawmill { get; set; } = default!;
///
@@ -55,6 +56,14 @@ public sealed partial class MessengerServerSystem : EntitySystem
SubscribeLocalEvent(OnServerDisconnected);
SubscribeLocalEvent(OnRoundRestart);
SubscribeLocalEvent(OnPlayerSpawnComplete);
+
+ InitializeSpam();
+ }
+
+ public override void Update(float frameTime)
+ {
+ base.Update(frameTime);
+ UpdateSpam(frameTime);
}
private void OnRoundRestart(EntityUid uid, MessengerServerComponent component, RoundRestartCleanupEvent args)
diff --git a/Content.Server/_Sunrise/Messenger/StationMessengerSpamComponent.cs b/Content.Server/_Sunrise/Messenger/StationMessengerSpamComponent.cs
new file mode 100644
index 0000000000..12714ddeaa
--- /dev/null
+++ b/Content.Server/_Sunrise/Messenger/StationMessengerSpamComponent.cs
@@ -0,0 +1,20 @@
+namespace Content.Server._Sunrise.Messenger;
+
+///
+/// Component for handling messenger spam timing on a station/entity.
+///
+[RegisterComponent]
+public sealed partial class StationMessengerSpamComponent : Component
+{
+ ///
+ /// Current timer in seconds.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public float Timer;
+
+ ///
+ /// Target time in seconds for the next spam wave.
+ ///
+ [DataField, ViewVariables(VVAccess.ReadWrite)]
+ public float NextSpamTime;
+}
diff --git a/Content.Shared/_Sunrise/Messenger/MessengerSpamPrototype.cs b/Content.Shared/_Sunrise/Messenger/MessengerSpamPrototype.cs
new file mode 100644
index 0000000000..5b0fa11b8d
--- /dev/null
+++ b/Content.Shared/_Sunrise/Messenger/MessengerSpamPrototype.cs
@@ -0,0 +1,22 @@
+using Robust.Shared.Prototypes;
+
+namespace Content.Shared._Sunrise.Messenger;
+
+[Prototype]
+public sealed partial class MessengerSpamPrototype : IPrototype
+{
+ [IdDataField]
+ public string ID { get; private set; } = default!;
+
+ [DataField(required: true)]
+ public string SenderDataset { get; private set; } = string.Empty;
+
+ [DataField(required: true)]
+ public string MessageDataset { get; private set; } = string.Empty;
+
+ [DataField]
+ public string? NameDataset { get; private set; }
+
+ [DataField]
+ public string? SurnameDataset { get; private set; }
+}
diff --git a/Content.Shared/_Sunrise/SunriseCCVars/SunriseCCVars.cs b/Content.Shared/_Sunrise/SunriseCCVars/SunriseCCVars.cs
index 4621a07b88..6512191bcc 100644
--- a/Content.Shared/_Sunrise/SunriseCCVars/SunriseCCVars.cs
+++ b/Content.Shared/_Sunrise/SunriseCCVars/SunriseCCVars.cs
@@ -590,4 +590,33 @@ public sealed partial class SunriseCCVars : CVars
///
public static readonly CVarDef MessengerFavoriteEmojis =
CVarDef.Create("messenger.favorite_emojis", "", CVar.ARCHIVE | CVar.CLIENTONLY);
+
+ /*
+ * Messenger Spam
+ */
+
+ ///
+ /// Enables the mechanic where players receive spam messages on their PDA.
+ ///
+ public static readonly CVarDef MessengerSpamEnabled =
+ CVarDef.Create("messenger.spam_enabled", true, CVar.SERVERONLY);
+
+ ///
+ /// Minimum time between spam waves in seconds.
+ ///
+ public static readonly CVarDef MessengerSpamMinTime =
+ CVarDef.Create("messenger.spam_min_time", 300f, CVar.SERVERONLY);
+
+ ///
+ /// Maximum time between spam waves in seconds.
+ ///
+ public static readonly CVarDef MessengerSpamMaxTime =
+ CVarDef.Create("messenger.spam_max_time", 600f, CVar.SERVERONLY);
+
+ ///
+ /// Percentage of players (0.0 to 1.0) who will receive spam during a wave.
+ ///
+ public static readonly CVarDef MessengerSpamPlayerPercentage =
+ CVarDef.Create("messenger.spam_player_percentage", 0.4f, CVar.SERVERONLY);
+
}
diff --git a/Resources/Locale/ru-RU/_Sunrise/messenger/spam.ftl b/Resources/Locale/ru-RU/_Sunrise/messenger/spam.ftl
new file mode 100644
index 0000000000..be54f26b0e
--- /dev/null
+++ b/Resources/Locale/ru-RU/_Sunrise/messenger/spam.ftl
@@ -0,0 +1,208 @@
+# Casino
+messenger-spam-casino-sender-1 = МегаСтавка — ставь или проиграешь!
+messenger-spam-casino-sender-2 = Онлайн казино МегаСтавка — 256 лет на рынке полулегальных азартных игр
+messenger-spam-casino-sender-3 = Сэкси дилеры в лучшем онлайн казино
+messenger-spam-casino-sender-4 = Все остальные онлайн казино — кидалы. Мы не такие.
+
+messenger-spam-casino-message-1 = Думаете жать одну кнопку на автомате это занятие для умственно неполноценных? Докажите что это не так сыграв у нас!
+messenger-spam-casino-message-2 = В нашем казино нет никаких «подкруток» или прочих нечестных приёмов. Вам просто не везёт!
+messenger-spam-casino-message-3 = Проиграли всю зарплату в друго казино? Проиграйте ещё одну у нас! В этот раз точно повезёт!
+messenger-spam-casino-message-4 = Зачем работать на корпорации, когда можно спустить свою жизнь чуть более приятным способом?
+messenger-spam-casino-message-5 = Игровая зависимость этом миф! Они просто не могут оторваться от 450 увлекательных игр в нашем казино!
+messenger-spam-casino-message-6 = Отделения МегаСтавки есть везде — от Элизиума до Аурума! Да, может даже на вашей станции!
+messenger-spam-casino-message-7 = В Онлайн Казино МегаСтавка мы не чешем колоду, гарантируем честную раздачу и наши колоды заряжены не в киосках как у конкурентов!
+
+# Dating
+messenger-spam-dating-sender-1 = СладкаяЦыпа
+messenger-spam-dating-sender-2 = Одинокая русская невеста
+messenger-spam-dating-sender-3 = ТаярскаяКрасотка57
+messenger-spam-dating-sender-4 = СкРеЛлОчКа))0
+messenger-spam-dating-sender-5 = Унаточка_чмаффки
+messenger-spam-dating-sender-6 = Фанатка_ЕРП_82
+messenger-spam-dating-sender-7 = Босс_Качалки93
+
+messenger-spam-dating-message-1 = Классные фотки на БыстрыхСвиданиях! Я бы пообщалась побольше, но у меня кончаются кредиты… если ты мне не скинешь немного XD (БыстрыеСвидания).
+messenger-spam-dating-message-2 = Подпишись на мой профиль — мой аккаунт [gender-female]@[gender-female].[pick("ru","ck","tj","ur","nt")], и получишь доступ к моим фото~
+messenger-spam-dating-message-3 = Слушай, у меня мало времени. Ты хочешь большой и чистой любви? Если хочешь, то ответь. Ещё никто не ответил…
+messenger-spam-dating-message-4 = У вас (1) новое сообщение от Куколки с 4 размером!
+messenger-spam-dating-message-5 = Я просто ОБОЖАЮ людей! Такие властные, сильные и умные… ммф… встретимся?
+messenger-spam-dating-message-6 = Я просто БЕЗ УМА от вульпакин! Хочу пошевелить с тобой хвостиками! Скинь аудио как ты воешь!
+messenger-spam-dating-message-7 = Я, как это говорится у меня на родине, «перфоманс артист».
+messenger-spam-dating-message-8 = Мой отец учил меня не стесняться, поэтому… не хочешь вступить в наш клуб? Всего 250 кредитов…
+messenger-spam-dating-message-9 = Я просто ВЛЮБЛЕНА в таких скреллов как ты! Такие большие, упругие и сочные щупальца на голове!
+messenger-spam-dating-message-10 = Я просто СХОЖУ С УМА от греев! Скинешь фотку своих больших глаз?
+messenger-spam-dating-message-11 = Плазмамен? А там внизу так же горячо?~
+messenger-spam-dating-message-12 = Все таяры такие милые? Обещаю почесать за ушком когда мы встретимся <3
+messenger-spam-dating-message-13 = Говорят что КПБ не устают в постели… это правда? Если так, то это свидание!
+messenger-spam-dating-message-14 = У Кидан такие большие глаза… скажем так, им есть на что посмотреть…
+messenger-spam-dating-message-15 = Легендарная гибкость и влажность слаймоменов… Хочу опробовать на себе!
+messenger-spam-dating-message-16 = Всегда хотелось пригреть драска… кстати, ты сегодня мальчик или девочка?
+messenger-spam-dating-message-17 = Надеюсь что диона переживёт отсутствие света под одеялом?~
+messenger-spam-dating-message-18 = Все остальные такие неженки… а вот воксы — самое то. Особенно пираты, ух… Встретимся?
+messenger-spam-dating-message-19 = У вас (2) новых просмотров профиля: Секси Скреллка и Сосед-по-Качалке
+
+# Finance
+messenger-spam-finance-sender-1 = Ассоциация Галактических Платежей
+messenger-spam-finance-sender-2 = Бюро Отличного Бизнеса
+messenger-spam-finance-sender-3 = Надёжные Электронные Платежи
+messenger-spam-finance-sender-4 = Финансовый Департамент NanoTransen
+messenger-spam-finance-sender-5 = Главное Казначейство
+
+messenger-spam-finance-message-1 = Роскошные часы по бросовым ценам! Есть экземпляры с древнего Альтама!
+messenger-spam-finance-message-2 = Часы, Ювелирные Изделия и Аксессуары из костей, Сумки и Кошельки из кожи
+messenger-spam-finance-message-3 = Внесите на счёт $100 и мгновенно получите назад $300! «Реально работает!» — Бобби
+messenger-spam-finance-message-4 = Кредиты для граждан ТСФ! Всего лишь от 99% годовых! Для остальных — 100%!
+messenger-spam-finance-message-5 = К нам поступила жалоба от одного из Ваших коллег по поводу его отношениий с Вами. После разбирательств вы были объявлены в розыск за домогательства. Я могу убедить его отозвать заявление за символические 5000 кредитов.
+messenger-spam-finance-message-6 = Мы убедительно просим Вас открыть ОТЧЕТ О ЖАЛОБЕ (прилагается), чтобы ответить на поступившую на вас жалобу, иначе вам будет начислен штраф.
+
+# Medicine
+messenger-spam-medicine-sender-1 = На часах полшестого?
+messenger-spam-medicine-sender-2 = Имеете проблемы с дисфункцией?
+messenger-spam-medicine-sender-3 = Слишком часто «болит голова»?
+
+messenger-spam-medicine-message-1 = Доктор Максман: РЕАЛЬНЫЕ доктора, РЕАЛЬНАЯ наука, РЕАЛЬНЫЕ результаты! Уникальная мазь на основе дегидроза фуфломицина!
+messenger-spam-medicine-message-2 = Доктор Максман был создан Джорджем Окуляром, сертифицированным ЦК урологом который лишь в этом секторе помог больше 70 000 пациентов с «мужскими проблемами». Может даже вашему начальнику!
+messenger-spam-medicine-message-3 = После семи лет исследований доктор Окуляр и его команда разработали эту простую и революционную формулу улучшения для мужчин. Редкий фуфломицин удалось синтезировать патентованым способом с помощью дегидроза монооксида дигидрогена!
+messenger-spam-medicine-message-4 = Мужчины всех видов сообщают об УДИВИТЕЛЬНОМ увеличении длины, ширины и выносливости.
+
+# Prince
+messenger-spam-prince-sender-1 = Др.
+messenger-spam-prince-sender-2 = Наследный принц
+messenger-spam-prince-sender-3 = Король-регент
+messenger-spam-prince-sender-4 = Профессор
+messenger-spam-prince-sender-5 = Капитан
+
+messenger-spam-prince-name-1 = Роберт
+messenger-spam-prince-name-2 = Альфред
+messenger-spam-prince-name-3 = Джозефат
+messenger-spam-prince-name-4 = Кингсли
+messenger-spam-prince-name-5 = Сехи
+messenger-spam-prince-name-6 = Жуан
+
+messenger-spam-prince-surname-1 = Мугавэ
+messenger-spam-prince-surname-2 = Нкем
+messenger-spam-prince-surname-3 = Гвембеш
+messenger-spam-prince-surname-4 = Абимбола
+messenger-spam-prince-surname-5 = Ндим
+messenger-spam-prince-surname-6 = Эну
+
+messenger-spam-prince-message-1 = ВАШИ СРЕДСТВА БЫЛИ ПЕРЕВЕДЕНЫ В БАНК РАЗВИТИЯ. ДЛЯ ДАЛЬНЕЙШЕГО ПЕРЕВОДА ДЕНЕЖНЫХ СРЕДСТВ СООБЩИТЕ СВОЙ НОМЕР АККАУНТА И ПИН-КОД.
+messenger-spam-prince-message-2 = Мы рады сообщить вам, что в связи с задержкой нам было поручено НЕМЕДЛЕННО перевести все средства на ваш счет. Для подтверждения счёта переведите 1000 кредитов. Не стоит волноваться, мы вернём вам кредиты после проверки.
+messenger-spam-prince-message-3 = Уважаемый получатель средств, сообщаем Вам, что перевод наследства окончательно одобрен и деньги готовы для получения Вами. Всё что Вам нужно сделать — отправить на этот же номер столько кредитов сколько Вы сможете. Это простая банковская формальность. В качестве благодарности мы вышлем Вам в 10 раз больше кредитов.
+messenger-spam-prince-message-4 = Из-за отсутствия у меня доверенных лиц мне требуется финансовый счет за пределами моего мира чтобы немедленно внести сумму в размере ПЯТИ МИЛЛИОНОВ кредитов.
+messenger-spam-prince-message-5 = Приветствую вас, сэр или мэм. Я с огромным сожалением сообщаю вам, что я умираю, и, из-за отсутствия наследников я выбрал вас, чтобы вы получили все мои сбережения за всю мою жизнь в размере 1,5 миллиарда кредитов. Но у меня нет вашего номера аккаунта и пин-кода, пожалуйста, сообщите их пока не поздно.
+
+# Adult
+messenger-spam-adult-sender-1 = Подразделение Морального Духа NanoTransen
+messenger-spam-adult-sender-2 = Вы одиноки?
+messenger-spam-adult-sender-3 = Дон Солевая
+messenger-spam-adult-sender-4 = www.wetskrell.nt
+
+messenger-spam-adult-message-1 = Подразделение Морального Духа NanoTransen предоставляет вам качественные развлекательные сайты. www.wetskrell.nt — один из таких сайтов и, специально для вас, ЦК сделало его бесплатным! Осталось только перейти по ссылке!
+messenger-spam-adult-message-2 = WetSkrell.nt является ксенофильским веб-сайтом, одобренным NT для использования членами экипажа мужского пола среди множества станций и аванпостов.
+messenger-spam-adult-message-3 = Wetskrell.nt обеспечивает высочайшее качество мужских развлечений для сотрудников Nanotrasen. Почти все модели старше 18 лет!
+messenger-spam-adult-message-4 = Просто введите номер и пин-код своего банковского аккаунта Nanotrasen. После этого вы получите безлимитный доступ ко ВСЕМУ контенту www.wetskrell.nt!
+
+# Lottery
+messenger-spam-lottery-sender-1 = Вы выиграли бесплатные билеты!
+messenger-spam-lottery-sender-2 = Нажмите здесь, чтобы получить свой приз!
+messenger-spam-lottery-sender-3 = Вы 1000-й посетитель!
+messenger-spam-lottery-sender-4 = Вы - счастливый обладатель главного приза!
+
+messenger-spam-lottery-message-1 = Вы выиграли билеты на новейший боевик БИТВА ЗА СТАНЦИЮ
+messenger-spam-lottery-message-2 = Вы выиграли билеты на новейшую криминальную драму ПО СЛЕДАМ МАРТЫШЕК
+messenger-spam-lottery-message-3 = Вы выиграли билеты на новейшую романтическую комедию БОЛЬШАЯ РАЗБОРКА В МАЛЕНЬКОЙ КРОВАТИ
+messenger-spam-lottery-message-4 = Вы выиграли билеты на скандальный блокбастер ПОЛНЫЙ ДОСТУП
+messenger-spam-lottery-message-5 = Вы выиграли билеты на скандальную комедию КАПИТАН МЁРТВ!
+messenger-spam-lottery-message-6 = Вы выиграли билеты на фильм ужасов УДАР СПЯЩЕГО КАРПА
+messenger-spam-lottery-message-7 = Вы выиграли билеты на слэшер ТУННЕЛЬНЫЙ СНЕГОВИК
+messenger-spam-lottery-message-8 = Вы выиграли билеты на трагикомедию БУДНИ ОХРАНЫ
+messenger-spam-lottery-message-9 = Вы выиграли билеты на %УДАЛЕНО АВТОМАТИЧЕСКИМ ФИЛЬТРОМ. СЛАВА NANOTRASEN%
+messenger-spam-lottery-message-10 = Вы выиграли билеты на короткометражный фильм ВСЕ КОНТРАКТЫ РАСТОРГНУТЫ
+messenger-spam-lottery-message-11 = Вы выиграли билеты на романтическую комедию ПЕРВЫЙ ХОНК!
+messenger-spam-lottery-message-12 = Вы выиграли билеты на приключенческий фильм ВОЛШЕБНИКИ ИЗ ДАЛЁКОГО КОСМОСА
+messenger-spam-lottery-message-13 = Вы выиграли билеты на фэнтези ПОСЛЕДНИЙ СЫН ХОНКОМАТЕРИ
+messenger-spam-lottery-message-14 = Вы выиграли билеты на боевик МЕСТЬ СИНДИКАТА, ЭПИЗОД III!
+messenger-spam-lottery-message-15 = Вы выиграли билеты на документальный фильм СЛАВА НТ
+messenger-spam-lottery-message-16 = Вы выиграли билеты на эротический фильм МОХНАТАЯ ПОДРУГА
+messenger-spam-lottery-message-17 = Вы выиграли билеты на эротический фильм КЛУБ КОЖЕВЕННОГО МАСТЕРСТВА
+messenger-spam-lottery-message-18 = Вы выиграли билеты на боевик РОБАСТБОРГ
+messenger-spam-lottery-message-19 = Вы выиграли билеты на драму 28 ОТТЕНКОВ ВУЛЬПАКИН
+messenger-spam-lottery-message-20 = Вы выиграли билеты на новейший триллер ЕРЕСЬ В ЦИРКЕ
+
+# Events
+messenger-spam-events-sender-1 = Тамада, баян, услуги
+messenger-spam-events-sender-2 = Баянист Тамада Дискотека
+messenger-spam-events-sender-3 = Свадьба за 1000 кредитов!
+messenger-spam-events-sender-4 = Организуем праздники несмотря на легальность!
+
+messenger-spam-events-message-1 = Увлекательные конкусы для ВАШЕЙ свадьбы!
+messenger-spam-events-message-2 = Невесты РЫДАЮТ от радости! Женихи теряют сознание от счастья!
+messenger-spam-events-message-3 = 7227051245544 — Игорь
+messenger-spam-events-message-4 = Только лучшие аниматоры со всего сектора! Специализированные конкурсы для сотрудников Nanotrasen! Посвящение в капитаны! Торт для начальника службы безопасности!
+messenger-spam-events-message-5 = я играть музыка кляссный беру дешево пиши да
+
+# Emergency
+messenger-spam-emergency-sender-1 = МАМА ПОМОГИ!
+messenger-spam-emergency-sender-2 = СРОЧНО!
+messenger-spam-emergency-sender-3 = Папа, я вляпался
+messenger-spam-emergency-sender-4 = ПОЖАЛУЙСТА!
+
+messenger-spam-emergency-message-1 = я врезался в корабль и офицер говорит что можно всё замять за 10000 кредитов, переведи пожалуйста
+messenger-spam-emergency-message-2 = ОНА САМА УМЕРЛА, Я НЕ ВИНОВАТ! УМОЛЯЮ, МНЕ НУЖНО 5000 НА НОВЫЙ МУЛЬТИПАСПОРТ! СКОРЕЕ, ОНИ СКОРО БУДУТ ЗДЕСЬ
+messenger-spam-emergency-message-3 = Меня машина убила! Переведи сколько можешь, иначе они не пришьют мне ноги обратно!
+messenger-spam-emergency-message-4 = Это твой сын, памаги! пропорщик говорид что может памочь! Иго номир щёта 133782, банк развития Цыфея
+
+# Cult
+messenger-spam-cult-sender-1 = Церковь Всех-и-Сразу
+messenger-spam-cult-sender-2 = Общественная организация «Слава Ран'ис»
+messenger-spam-cult-sender-3 = Орден «ПРОТИВ ВУЛЬП»
+messenger-spam-cult-sender-4 = Движение «ЗА ВУЛЬП»
+messenger-spam-cult-sender-5 = КРОВЬ БОГУ КРОВИ
+
+messenger-spam-cult-message-1 = Если вам небезразлично наше дело, заходите к нам по адресу: Сектор Ардей, планета Тифон-14, здание №1756B, этаж -76, офис 4
+messenger-spam-cult-message-2 = Наши идею могут показаться немного радикальными, но, уверяю вас, это всего лишь слухи. Напоминаем, что следущая всеобщая молитва в пятницу, и приносите жертвоприношения с собой.
+messenger-spam-cult-message-3 = Привет! Тебе одиноко? Не видишь смысла в жизни? Ну что ж, тогда мы будем рады тебе! Всего за 500 кредитов в месяц ты можешь вступить в наше дружное общество.
+messenger-spam-cult-message-4 = Вам же не всё равно? А?! Или всё равно?! Ты бесхребетная крыса или уверенный в себе гуманоид?! Если у тебя кишка не тонка, то найдёшь нас сам.
+messenger-spam-cult-message-5 = Пожалуйста, спасите меня, я здесь против своей воли.
+messenger-spam-cult-message-6 = Вы уверены что живёте праведной жизнью? Если нет, пошлите нам 100 кредитов и мы помолимся за вас. Если да, то тоже пошлите, нам нужны пожертвования.
+messenger-spam-cult-message-7 = Мы знаем. Мы найдём тебя сами, не нужно ничего делать.
+
+# Pets
+messenger-spam-pets-sender-1 = Экзотические питомцы
+messenger-spam-pets-sender-2 = Друзья наши меньшие
+messenger-spam-pets-sender-3 = Питомцы, домашние и не очень
+messenger-spam-pets-sender-4 = Торговцы Элизиума
+
+messenger-spam-pets-message-1 = Торговый корабль «Пупсик» приглашает вас к себе на борт. Большой выбор свиней и кабанов самых разных пород, включая редких взрывных.
+messenger-spam-pets-message-2 = Дикие родственники таяр, вульпакин, воксов, киданов, унатхов, людей в ассортименте. Внимание! Владение нашим товаром может быть запрещено вашим законодательством!
+messenger-spam-pets-message-3 = Если вы не купите у нас хоть что-то, мы пристрелим щенка. Вы думаете я шучу? У вас есть 1 час.
+messenger-spam-pets-message-4 = ГРОМ 74 27 99 14. Геннадий, Роман, Олег, Михаил, 7 4 2 7 9 9 1 4
+messenger-spam-pets-message-5 = Магазин «Мышеловка»! Мыши, крысы, большие и маленькие, плотоядные и не очень! При покупке колесо сыра в подарок! Одобрено Федерацией Мышей!
+messenger-spam-pets-message-6 = Огромный выбор питомцев, вкусные корма, защита от блох и вшей и акссесуары для друзей наших меньших, а так же вульпакин и таяр.
+
+# Weapons
+messenger-spam-weapons-sender-1 = Оружие для всей семьи
+messenger-spam-weapons-sender-2 = Стволы по дешёвке
+messenger-spam-weapons-sender-3 = ПУШКИ ПУШКИ ПУШКИ
+messenger-spam-weapons-sender-4 = Большие пушки для больших парней
+messenger-spam-weapons-sender-5 = Мануфактура «У Бобби»
+
+messenger-spam-weapons-message-1 = Самый большой выбор огнестрела в секторе. От дамских пистолетов до снайперской винтовки! Для совершения покупки требуется лицензия на владение оружием.
+messenger-spam-weapons-message-2 = Лучшее от Синдиката. Пистолет %УДАЛЕНО%, усыпляющая %УДАЛЕНО%, пробивающая стены %УДАЛЕНО% и даже легендарный %УДАЛЕНО% меч. Агентам скидки, сотрудникам НТ бесплатн…9э%8%?3Р1… ВНИМАНИЕ! Перехвачено враждебное сообщение. Не обращайте внимания. Возвращайтесь к работе. Слава Nanotrasen!
+messenger-spam-weapons-message-3 = Нужно что-то особое? Как насчёт магнума что сделает дыру в стене из пластали? Пневматический зонтик-ружьё? Надувной клоун со взрывчаткой внутри? Если вы об этом подумали, у нас это есть.
+messenger-spam-weapons-message-4 = Давай к делу. Тебе нужно оружие? Меня зовут Борис и у меня для тебя есть пушки. Не спрашивай откуда, просто покупай.
+messenger-spam-weapons-message-5 = Гранаты. Дымовые шашки. Тротил. Бомбы. Снаряды. Мины. С4. Ракеты. Биологическое оружие. Ядерные боеголовки. Распродажа! Успей, пока не урвали! Никаких лицензий, только бабки!
+
+# Error
+messenger-spam-error-sender-1 = ОШ;Б…;кА
+messenger-spam-error-sender-2 = 25-j*%...o1q
+messenger-spam-error-sender-3 = СБОЙ СИСТЕМЫ СООБЩЕНИЙ
+messenger-spam-error-sender-4 = ОШИБКА
+
+messenger-spam-error-message-1 = …от этого корабля, блядь. Ты кто такой, сука? Не пиши сюда больше блядь, я тебя найд…
+messenger-spam-error-message-2 = …имание, агент. Дальше будут перечислены ваши цели. Никто не должен уйти живым. Первую цель зов…
+messenger-spam-error-message-3 = …ася, хватить, блядь! Водки он напился, идиот. У НАС ЗАВТРА НА ТРАНС СОЛНЕЧНУЮ ФЕДЕРАЦИЮ НАЛЁТ, КАКАЯ ВОДКА! Сука, офицер СССП ещё называе…
+messenger-spam-error-message-4 = …ы меня не любишь? Потому что я скрелл?! …извини, я сорвалась. Я вся на нервах из-за работы… Прилетай ко мне, я соску…
+messenger-spam-error-message-5 = …еальные стулья! У нас лучшие стулья в секторе! С обивкой и без, с кожей и с инкрустированным ураном! Есть даже передвижные стулья с педалями! Кроме тог…
+messenger-spam-error-message-6 = …а сковороду тем временем налейте еще немного масла и выложите тертую свеклу. Обжарьте пару минут и добавьте уксус. Тушите еще минут 5, а после выложите томатную пасту. Томите на медленном огне еще 5-7 минут. Зате…
diff --git a/Resources/Prototypes/Entities/Stations/nanotrasen.yml b/Resources/Prototypes/Entities/Stations/nanotrasen.yml
index bab09318ac..6acdd0c18d 100644
--- a/Resources/Prototypes/Entities/Stations/nanotrasen.yml
+++ b/Resources/Prototypes/Entities/Stations/nanotrasen.yml
@@ -29,6 +29,7 @@
- BaseStationNanotrasen
- BaseStationDeliveries
# Sunrise-Start
+ - BaseStationSpam
- BaseStationTransitHub
- BaseStationDontSelling
- BaseStationPlanetPrison
diff --git a/Resources/Prototypes/_Sunrise/Datasets/messenger_spam.yml b/Resources/Prototypes/_Sunrise/Datasets/messenger_spam.yml
new file mode 100644
index 0000000000..2b90ee5cda
--- /dev/null
+++ b/Resources/Prototypes/_Sunrise/Datasets/messenger_spam.yml
@@ -0,0 +1,167 @@
+- type: localizedDataset
+ id: MessengerSpamCasinoSenders
+ values:
+ prefix: messenger-spam-casino-sender-
+ count: 4
+
+- type: localizedDataset
+ id: MessengerSpamCasinoMessages
+ values:
+ prefix: messenger-spam-casino-message-
+ count: 7
+
+- type: localizedDataset
+ id: MessengerSpamDatingSenders
+ values:
+ prefix: messenger-spam-dating-sender-
+ count: 7
+
+- type: localizedDataset
+ id: MessengerSpamDatingMessages
+ values:
+ prefix: messenger-spam-dating-message-
+ count: 19
+
+- type: localizedDataset
+ id: MessengerSpamFinanceSenders
+ values:
+ prefix: messenger-spam-finance-sender-
+ count: 5
+
+- type: localizedDataset
+ id: MessengerSpamFinanceMessages
+ values:
+ prefix: messenger-spam-finance-message-
+ count: 6
+
+- type: localizedDataset
+ id: MessengerSpamMedicineSenders
+ values:
+ prefix: messenger-spam-medicine-sender-
+ count: 3
+
+- type: localizedDataset
+ id: MessengerSpamMedicineMessages
+ values:
+ prefix: messenger-spam-medicine-message-
+ count: 4
+
+- type: localizedDataset
+ id: MessengerSpamPrinceSenders
+ values:
+ prefix: messenger-spam-prince-sender-
+ count: 5
+
+- type: localizedDataset
+ id: MessengerSpamPrinceNames
+ values:
+ prefix: messenger-spam-prince-name-
+ count: 6
+
+- type: localizedDataset
+ id: MessengerSpamPrinceSurnames
+ values:
+ prefix: messenger-spam-prince-surname-
+ count: 6
+
+- type: localizedDataset
+ id: MessengerSpamPrinceMessages
+ values:
+ prefix: messenger-spam-prince-message-
+ count: 5
+
+- type: localizedDataset
+ id: MessengerSpamAdultSenders
+ values:
+ prefix: messenger-spam-adult-sender-
+ count: 4
+
+- type: localizedDataset
+ id: MessengerSpamAdultMessages
+ values:
+ prefix: messenger-spam-adult-message-
+ count: 4
+
+- type: localizedDataset
+ id: MessengerSpamLotterySenders
+ values:
+ prefix: messenger-spam-lottery-sender-
+ count: 4
+
+- type: localizedDataset
+ id: MessengerSpamLotteryMessages
+ values:
+ prefix: messenger-spam-lottery-message-
+ count: 20
+
+- type: localizedDataset
+ id: MessengerSpamEventsSenders
+ values:
+ prefix: messenger-spam-events-sender-
+ count: 4
+
+- type: localizedDataset
+ id: MessengerSpamEventsMessages
+ values:
+ prefix: messenger-spam-events-message-
+ count: 5
+
+- type: localizedDataset
+ id: MessengerSpamEmergencySenders
+ values:
+ prefix: messenger-spam-emergency-sender-
+ count: 4
+
+- type: localizedDataset
+ id: MessengerSpamEmergencyMessages
+ values:
+ prefix: messenger-spam-emergency-message-
+ count: 4
+
+- type: localizedDataset
+ id: MessengerSpamCultSenders
+ values:
+ prefix: messenger-spam-cult-sender-
+ count: 5
+
+- type: localizedDataset
+ id: MessengerSpamCultMessages
+ values:
+ prefix: messenger-spam-cult-message-
+ count: 7
+
+- type: localizedDataset
+ id: MessengerSpamPetsSenders
+ values:
+ prefix: messenger-spam-pets-sender-
+ count: 4
+
+- type: localizedDataset
+ id: MessengerSpamPetsMessages
+ values:
+ prefix: messenger-spam-pets-message-
+ count: 6
+
+- type: localizedDataset
+ id: MessengerSpamWeaponsSenders
+ values:
+ prefix: messenger-spam-weapons-sender-
+ count: 5
+
+- type: localizedDataset
+ id: MessengerSpamWeaponsMessages
+ values:
+ prefix: messenger-spam-weapons-message-
+ count: 5
+
+- type: localizedDataset
+ id: MessengerSpamErrorSenders
+ values:
+ prefix: messenger-spam-error-sender-
+ count: 4
+
+- type: localizedDataset
+ id: MessengerSpamErrorMessages
+ values:
+ prefix: messenger-spam-error-message-
+ count: 6
diff --git a/Resources/Prototypes/_Sunrise/Entities/Stations/base.yml b/Resources/Prototypes/_Sunrise/Entities/Stations/base.yml
index aa7e571f47..bc93e34ca6 100644
--- a/Resources/Prototypes/_Sunrise/Entities/Stations/base.yml
+++ b/Resources/Prototypes/_Sunrise/Entities/Stations/base.yml
@@ -105,3 +105,9 @@
abstract: true
components:
- type: StationRandomXenoArtifact
+
+- type: entity
+ id: BaseStationSpam
+ abstract: true
+ components:
+ - type: StationMessengerSpam
diff --git a/Resources/Prototypes/_Sunrise/Messenger/messenger_spam.yml b/Resources/Prototypes/_Sunrise/Messenger/messenger_spam.yml
new file mode 100644
index 0000000000..be61d259b9
--- /dev/null
+++ b/Resources/Prototypes/_Sunrise/Messenger/messenger_spam.yml
@@ -0,0 +1,66 @@
+- type: messengerSpam
+ id: SpamCasino
+ senderDataset: MessengerSpamCasinoSenders
+ messageDataset: MessengerSpamCasinoMessages
+
+- type: messengerSpam
+ id: SpamDating
+ senderDataset: MessengerSpamDatingSenders
+ messageDataset: MessengerSpamDatingMessages
+
+- type: messengerSpam
+ id: SpamFinance
+ senderDataset: MessengerSpamFinanceSenders
+ messageDataset: MessengerSpamFinanceMessages
+
+- type: messengerSpam
+ id: SpamMedicine
+ senderDataset: MessengerSpamMedicineSenders
+ messageDataset: MessengerSpamMedicineMessages
+
+- type: messengerSpam
+ id: SpamPrince
+ senderDataset: MessengerSpamPrinceSenders
+ nameDataset: MessengerSpamPrinceNames
+ surnameDataset: MessengerSpamPrinceSurnames
+ messageDataset: MessengerSpamPrinceMessages
+
+- type: messengerSpam
+ id: SpamAdult
+ senderDataset: MessengerSpamAdultSenders
+ messageDataset: MessengerSpamAdultMessages
+
+- type: messengerSpam
+ id: SpamLottery
+ senderDataset: MessengerSpamLotterySenders
+ messageDataset: MessengerSpamLotteryMessages
+
+- type: messengerSpam
+ id: SpamEvents
+ senderDataset: MessengerSpamEventsSenders
+ messageDataset: MessengerSpamEventsMessages
+
+- type: messengerSpam
+ id: SpamEmergency
+ senderDataset: MessengerSpamEmergencySenders
+ messageDataset: MessengerSpamEmergencyMessages
+
+- type: messengerSpam
+ id: SpamCult
+ senderDataset: MessengerSpamCultSenders
+ messageDataset: MessengerSpamCultMessages
+
+- type: messengerSpam
+ id: SpamPets
+ senderDataset: MessengerSpamPetsSenders
+ messageDataset: MessengerSpamPetsMessages
+
+- type: messengerSpam
+ id: SpamWeapons
+ senderDataset: MessengerSpamWeaponsSenders
+ messageDataset: MessengerSpamWeaponsMessages
+
+- type: messengerSpam
+ id: SpamError
+ senderDataset: MessengerSpamErrorSenders
+ messageDataset: MessengerSpamErrorMessages
diff --git a/Tools/_sunrise/Schemas/ignore_list.yml b/Tools/_sunrise/Schemas/ignore_list.yml
index ac634b76ca..21b59040ad 100644
--- a/Tools/_sunrise/Schemas/ignore_list.yml
+++ b/Tools/_sunrise/Schemas/ignore_list.yml
@@ -182,7 +182,9 @@ ignore_list:
- 'Net-ERR*?*%'
- 'Holo Girl'
- 'RobustChat'
-
+ - 'www.wetskrell.nt'
+ - '25-j*%...o1q'
+
ignore_files:
- 'italian.ftl'
- 'russian.ftl'