-- GENERATED by frontend/build.cjs from config/config.lua and config/media.lua - do not edit. -- Escrowed snapshot of the shipped defaults used by the Phone Configurator. local realConfig = Config Config = {} --[[ Sky Phone configuration General settings live in this file. Media providers and upload limits live in config/media.lua, while translations remain in config/locales/*.lua. Sections marked "SERVER ONLY" are guarded with IsDuplicityVersion(), so passwords, API keys, migration settings, and server-owned locations are not applied by game clients. Keep option names unchanged. Restart sky_phone after editing this file. ]] -- ============================================================================= -- Core, framework and device -- ============================================================================= Config.Bridge = { Framework = "auto", -- auto, esx, qbox, qb -- auto, ak47, codem, core, jaksam, jpr, lj, mf, one, origen, ox, ps, qb, qs, smx, tgiann, hex, esx -- Compatibility aliases: qb-inv -> qb, qbox -> ox Inventory = "auto", Locale = "en", CallbackTimeout = 15000, Debug = false, -- true: show debug/info output; warnings and errors are always shown } Config.Command = "phone" Config.Phone = { Item = "phone", Unique = true, -- true: data follows each phone item; false: one persistent phone per character; forced false for metadata-free inventories Keybind = "F1", -- false disables the configurable phone key mapping OpenRequestsPerMinute = 20, AllowMovement = true, -- true: game input stays active while the mobile phone is open HoldToLook = { Enabled = true, -- hold the configured control to hide the cursor and look around; independent of AllowMovement Control = 19, -- INPUT_CHARACTER_WHEEL (Left Alt by default) }, DevelopmentCommand = true, DeviceName = "iFruit Phone", } -- Server-wide availability for bundled apps. Set an entry to false to hide it -- from every phone, the App Store and per-device app management. Config.Apps = { ["app-store"] = true, banking = true, billing = true, calculator = true, calendar = true, camera = true, citymarkt = true, citywarn = true, clock = true, companies = true, crewlink = true, crypto = true, darkchat = true, feather = true, flare = true, fliptok = true, garage = true, health = true, house = true, ["local-pages"] = true, mail = true, map = true, memory = true, memos = true, messages = true, minesweeper = true, music = true, ["neon-drop"] = true, notes = true, ["number-merge"] = true, phone = true, photos = true, picstagram = true, radio = true, settings = true, ["sky-flappy"] = true, skyride = true, snake = true, ["tower-stack"] = true, weather = true, ["weazel-news"] = true, } Config.TestData = { Enabled = false, -- development/test servers only; keep disabled in production Command = "phonetestdata", AdminOnly = false, -- enable only on development servers; every run is scoped to the executing player's phone } Config.CustomApps = { Enabled = true, BundledApps = true, ExternalApps = true, Debug = false, -- detailed client traces for exports, registration, catalog sync and lifecycle events ReadyTimeoutMs = 8000, MaximumMessageBytes = 65536, MaximumStorageBytesPerApp = 262144, MaximumStorageValueBytes = 65536, -- Bridge v1 ceiling; lower values tighten the server policy. MaximumStorageKeyLength = 64, -- Bridge v1 ceiling; lower values tighten the server policy. MaximumStorageKeysPerApp = 128, StorageRequestsPerMinute = 120, TrustedAdapters = {}, } Config.Security = { MaximumAttempts = 5, LockSeconds = 30, AttemptsPerMinute = 12, } Config.AdminPanel = { Enabled = true, Command = "phonepanel", MaximumPlayers = 128, ReadRequestsPerMinute = 60, ActionRequestsPerMinute = 30, CredentialRevealsPerMinute = 6, AuditLimit = 40, ActivityLimit = 40, } Config.Sim = { Enabled = true, -- false: devices receive a persistent random number automatically; forced false for metadata-free inventories RegisteredItem = "sky_phone_sim_registered", AnonymousItem = "sky_phone_sim_anonymous", NumberLength = 10, -- total number of digits, including NumberPrefix NumberPrefix = "", -- digits only; use "555", not "555-" NumberGroups = { 3, 3, 4 }, -- display groups separated by spaces } -- ============================================================================= -- Calls, voice and radio -- ============================================================================= Config.Speaker = { Enabled = true, -- global phone and radio speaker controls } Config.Calls = { VoiceProvider = "pma", -- auto, yaca (alias: yaca-voice), pma (alias: pma-voice), saltychat (alias: salty) RingSeconds = 30, ContactNameMaxLength = 80, ContactNotesMaxLength = 500, RecentPageSize = 100, } Config.Payphones = { Enabled = true, -- Existing world props with these models are detected automatically. Props = { "prop_phonebox_01b", "p_phonebox_01b_s", "prop_phonebox_01a", "prop_phonebox_04", }, -- Additional booths are spawned only at these custom positions. CustomProp = "prop_phonebox_01b", CustomLocations = { -- vector4(x, y, z, heading), }, ReplacementProp = "sf_prop_sf_phonebox_01b_s", PricePerSecond = 1, PaymentAccount = "cash", -- cash or bank Currency = "$", NoAnswerTimeoutSeconds = 30, CallerNumber = "PAYPHONE", InteractionDistance = 1.8, ServerValidationDistance = 3.0, MaximumCallDistance = 4.0, ScanDistance = 25.0, ScanIntervalMs = 1000, ModelLoadTimeoutMs = 5000, Animation = { Dictionary = "anim@scripted@payphone_hits@male@", PedClip = "FXFR_PAV_1_INTRO_MALE", PropClip = "FXFR_PAV_1_INTRO_PHONE", HangupDurationMs = 2000, }, } Config.Radio = { VoiceProvider = "auto", -- auto, yaca, pma, saltychat DefaultVolume = 50, HistoryLimit = 8, FrequencyMin = 0.1, FrequencyMax = 999.9, FrequencyDecimals = 1, AllowSecondary = true, Notifications = false, AutoRejoin = false, DisplayName = { Enabled = true, MaxLength = 32, AllowedJobs = { -- Job name = minimum grade. Unlisted jobs cannot set a radio display name. police = 0, sheriff = 0, fib = 0, army = 0, ambulance = 0, }, }, Hud = { Enabled = true, SpeakerPersistMilliseconds = 3000, Position = { Horizontal = "right", -- left or right Vertical = "top", -- top or bottom HorizontalOffset = 2.0, -- vh VerticalOffset = 30.0, -- vh }, }, Badge = { Enabled = true, MaxLength = 8, ForbiddenPatterns = { "88", "1488", "18", "14", "28", "198" }, }, LockedChannels = { { range = { 0.1, 100.0 }, jobs = { police = true, sheriff = true, fib = true, army = true, ambulance = true, }, }, }, } -- ============================================================================= -- Phone presentation and animations -- ============================================================================= Config.Animations = { Enabled = true, PropModel = "prop_npc_phone_02", PropBone = 28422, LoadTimeoutMs = 5000, ContextPollMs = 250, Dictionaries = { OnFoot = "cellphone@", Driver = "anim@cellphone@in_car@ds", Passenger = "anim@cellphone@in_car@ps", Camera = "cellphone@self", }, Clips = { TextIn = "cellphone_text_in", TextRead = "cellphone_text_read_base", TextOut = "cellphone_text_out", TextToCall = "cellphone_text_to_call", CallListen = "cellphone_call_listen_base", CallToText = "cellphone_call_to_text", CallOut = "cellphone_call_out", Camera = "selfie", }, Transforms = { Portrait = { position = vector3(0.0, 0.0, 0.0), rotation = vector3(0.0, 0.0, 0.0), }, Landscape = { position = vector3(0.0, 0.0, 0.0), rotation = vector3(0.0, 0.0, 90.0), }, }, } -- ============================================================================= -- Built-in applications -- ============================================================================= Config.Messages = { BodyMaxLength = 2000, ConversationScanLimit = 1000, ThreadPageSize = 200, SendsPerMinute = 30, MediaLoadsPerMinute = 120, VoiceMaxDurationMs = 30000, VoiceMaxBase64Length = 180000, VoiceWaveformSamples = 48, VideoMaxDurationMs = 30000, DeleteBatchSize = 20, } Config.Memos = { MaximumCount = 100, MaximumDurationMs = 300000, MaximumBytes = 2 * 1024 * 1024, MaximumWaveformSamples = 96, TitleMaxLength = 120, NoteMaxLength = 2000, UploadsPerMinute = 10, WritesPerMinute = 60, ListsPerMinute = 60, MaximumPendingUploads = 1, UploadSessionTimeoutMs = 60000, } Config.EasyShare = { Enabled = true, DefaultVisibility = "everyone", -- everyone, contacts or hidden MaximumDistance = 15.0, HistoryLimit = 50, PendingSeconds = 30, TransferDurationMs = 3000, RequestsPerMinute = 12, BootstrapRequestsPerMinute = 30, VisibilityUpdatesPerMinute = 10, ActionsPerMinute = 30, PayloadMaxBytes = 24000, } Config.DarkChat = { AliasMaxLength = 32, BodyMaxLength = 2000, ThreadPageSize = 200, SendsPerMinute = 30, ActionsPerMinute = 60, ReportsPerDay = 10, VoiceMaxDurationMs = 60000, VoiceMaxBase64Length = 360000, VoiceWaveformSamples = 48, CleanupIntervalSeconds = 30, CleanupBatchSize = 250, AllowedDisappearTimers = { [0] = true, [-1] = true, -- after reading [60] = true, [300] = true, [3600] = true, [86400] = true, [604800] = true, }, } Config.Mail = { Domain = "ifruit.com", LocalPartMinLength = 3, LocalPartMaxLength = 32, PasswordMinLength = 6, PasswordMaxLength = 64, SubjectMaxLength = 120, BodyMaxLength = 20000, MaxRecipients = 10, PageSize = 50, AuthAttemptsPerMinute = 5, MailboxNameMaxLength = 50, MaxMailboxes = 20, MailboxRequestsPerMinute = 12, DeleteBatchSize = 50, DeleteRequestsPerMinute = 12, } Config.Banking = { Currency = "$", MinimumAmount = 1, MaximumAmount = 1000000, ActionsPerMinute = 12, HistoryLimit = 50, } Config.Health = { DailyStepGoal = 8000, SampleIntervalMs = 500, ReportIntervalSeconds = 30, ReportsPerMinute = 4, MaximumSpeedMetersPerSecond = 12.0, EmergencyNumber = "911", ProfileTextMaxLength = 500, } Config.Billing = { Enabled = true, Currency = "$", PaymentAccount = "bank", -- bank or cash MinimumAmount = 1, MaximumAmount = 1000000, PageSize = 30, UrgentLimit = 5, ActionsPerMinute = 8, AllowDisputes = true, DefaultDueDays = 7, MaximumTitleLength = 160, MaximumDescriptionLength = 1000, } Config.Garage = { System = "auto", -- auto, custom, esx, qb, qbox, ak47, bp, cd, codem, ds-servercreator, hex, jg, my, okok, op, quasar, rx, vms, ws, zyke_garages MaximumVehicles = 250, RequestsPerMinute = 30, VehicleImages = { Enabled = true, UrlTemplate = "https://cdn.sky-systems.net/vehicles/{model}.png", -- Optional spawn-name overrides for garages that only store model hashes. -- Example: [970598228] = "sultan", ModelNames = {}, }, Custom = { Table = "", OwnerColumn = "", }, Valet = { Enabled = true, Price = 750, Account = "bank", -- bank or cash RequestsPerMinute = 3, CooldownSeconds = 60, TimeoutSeconds = 180, SpawnDistance = 110.0, ArrivalDistance = 14.0, DriveSpeed = 20.0, DrivingStyle = 786603, DriverModel = "s_m_m_autoshop_01", -- The current valet driver route supports road vehicles. Keep non-road types disabled. VehicleTypes = { car = true, bike = true, boat = false, plane = false, helicopter = false, }, }, } Config.Housing = { System = "auto", -- auto, rtx, quasar, tgiann, vms, rx, nolag, sn, esx_property, qbx_properties AutoPriority = { "esx_property", "qbx_properties", "rtx", "quasar", "tgiann", "vms", "rx", "nolag", "sn" }, MaximumProperties = 50, OverviewRequestsPerMinute = 30, ActionsPerMinute = 12, Camera = { HeightAboveEntrance = 2.5, FieldOfView = 55.0, MinimumFieldOfView = 20.0, MaximumFieldOfView = 75.0, RotateSpeed = 0.65, ExitControl = 177, -- Backspace NightVisionControl = 38, -- E ZoomInControl = 241, -- Mouse wheel up ZoomOutControl = 242, -- Mouse wheel down LeftControl = 174, RightControl = 175, UpControl = 172, DownControl = 173, }, } Config.Marketplace = { PageSize = 20, MessagePageSize = 50, OfferHistorySize = 50, MaxActiveListings = 15, MaxImages = 6, TitleMinLength = 5, TitleMaxLength = 70, DescriptionMinLength = 20, DescriptionMaxLength = 2000, MessageMaxLength = 1000, MaximumPrice = 100000000, ListingLifetimeDays = 7, Categories = { "vehicles", "property", "electronics", "clothing", "tools", "leisure", "services", "jobs", "wanted", "other", }, Districts = { "los_santos", "vinewood", "vespucci", "south_los_santos", "sandy_shores", "paleto_bay", "blaine_county", }, PhotoGradients = { "linear-gradient(145deg, #ff9a62, #5f2c82 58%, #141e30)", "linear-gradient(160deg, #67d5b5, #26648e 55%, #0b132b)", "linear-gradient(135deg, #fbc2eb, #a6c1ee 48%, #302b63)", "linear-gradient(150deg, #f6d365, #fda085 45%, #512b58)", "linear-gradient(145deg, #ff6b6b, #845ec2 52%, #0f2027)", "linear-gradient(150deg, #00c9a7, #4d8076 46%, #1f3a5f)", "linear-gradient(135deg, #ffc75f, #f96d80 48%, #4b4453)", }, } Config.LocalPages = { PageSize = 20, MaxImages = 6, ProfileHandleMinLength = 3, ProfileHandleMaxLength = 24, ProfileBioMaxLength = 160, TitleMinLength = 5, TitleMaxLength = 80, BodyMinLength = 10, BodyMaxLength = 1500, Categories = { "recommendation", "wanted", "service", "event", "place", "community" }, CityMarktSharesPerDay = 1, } -- ============================================================================= -- Social applications -- ============================================================================= Config.FlipTok = { PageSize = 12, CaptionMaxLength = 500, CommentMaxLength = 300, BioMaxLength = 160, PasswordMinLength = 8, PasswordMaxLength = 72, MaxVideoDurationMs = 300000, MaxPostMedia = 10, MusicTracks = {}, VerifyCommand = "fliptokverify", ReportWebhookConvar = "sky_phone_fliptok_report_webhook", } Config.Picstagram = { PageSize = 12, CommentPageSize = 100, MaxPostMedia = 5, CaptionMaxLength = 800, CommentMaxLength = 300, BioMaxLength = 160, LocationMaxLength = 80, StoryTextMaxLength = 160, StoryLifetimeSeconds = 24 * 60 * 60, PasswordMinLength = 8, PasswordMaxLength = 72, PostsPerMinute = 6, StoriesPerMinute = 6, CommentsPerMinute = 20, ReportDetailsMaxLength = 500, ReportReasons = { "spam", "harassment", "dangerous", "illegal", "other" }, VerifyCommand = "picstagramverify", } Config.Feather = { PageSize = 20, TextMaxLength = 360, BioMaxLength = 160, DisplayNameMaxLength = 50, HandleMaxLength = 30, SearchMaxLength = 80, HashtagMaxLength = 64, TrendingTopicLimit = 10, ReportDetailsMaxLength = 500, MaxImages = 4, PostsPerMinute = 8, ActionsPerMinute = 90, ReportsPerDay = 10, } -- ============================================================================= -- Utilities, groups and transport -- ============================================================================= Config.MapMarkers = { MaximumMarkers = 50, LabelMaxLength = 40, ActionsPerMinute = 60, } Config.CrewLink = { UsernameMinLength = 3, UsernameMaxLength = 20, PasswordMinLength = 8, PasswordMaxLength = 72, GroupNameMinLength = 3, GroupNameMaxLength = 32, MaximumGroupsPerProfile = 5, MaximumMembersPerGroup = 16, InviteCodeLength = 8, InviteLifetimeSeconds = 30, NearbyInviteDistance = 5.0, NearbyScanLimit = 12, PingLabelMaxLength = 48, PingLifetimeSeconds = 300, MaximumActivePings = 12, ActionsPerMinute = 30, LiveRequestsPerMinute = 120, OverheadRefreshMilliseconds = 3000, OverheadDistance = 50.0, ExternalPingResources = { -- ["example_resource"] = true, }, } Config.Calendar = { TitleMaxLength = 120, NoteMaxLength = 2000, MaximumDurationSeconds = 7 * 24 * 60 * 60, MaximumQuerySeconds = 370 * 24 * 60 * 60, PastEditSeconds = 365 * 24 * 60 * 60, FutureSeconds = 5 * 365 * 24 * 60 * 60, ReminderPollSeconds = 15, } Config.SkyRide = { PaymentAccount = "bank", Currency = "$", ProfileNameMinLength = 2, ProfileNameMaxLength = 50, DistanceUnit = "kilometer", -- kilometer or mile QuoteLifetimeSeconds = 120, HistoryLimit = 50, ReadsPerMinute = 120, ActionsPerMinute = 30, QuotesPerMinute = 20, RecoveryIntervalSeconds = 15, PaymentPendingRecoverySeconds = 30, PickupSelectionRadius = 150.0, ArrivalRadius = 40.0, CompletionRadius = 80.0, MinimumDistanceMeters = 250, MaximumDistanceMeters = 40000, RouteDistanceMultiplier = 1.25, AverageSpeedMetersPerSecond = 12.0, DriverPayoutPercent = 85, RatingCommentMaxLength = 300, MaximumTip = 10000, CustomFare = { Enabled = true, MinimumPrice = 5, MaximumPrice = 100000, MinimumCalculatedMultiplier = 0.5, MaximumCalculatedMultiplier = 3.0, }, DriverJobs = { taxi = 0, }, Services = { { Id = "taxi", Seats = 4, EtaMinutes = 3, BaseFare = 12, PricePerKilometer = 18, PricePerMile = 29, PricePerMinute = 1, MinimumFare = 15, }, { Id = "comfort", Seats = 4, EtaMinutes = 5, BaseFare = 16, PricePerKilometer = 24, PricePerMile = 39, PricePerMinute = 2, MinimumFare = 22, }, { Id = "xl", Seats = 6, EtaMinutes = 7, BaseFare = 20, PricePerKilometer = 30, PricePerMile = 48, PricePerMinute = 2, MinimumFare = 28, }, { Id = "premium", Seats = 4, EtaMinutes = 8, BaseFare = 28, PricePerKilometer = 40, PricePerMile = 64, PricePerMinute = 3, MinimumFare = 38, }, }, QuickLocations = { { Id = "legion-square", Label = "Legion Square", Coords = vector3(-265.1, -960.2, 31.2), }, { Id = "diamond-casino", Label = "Diamond Casino", Coords = vector3(925.2, 46.4, 81.1), }, { Id = "airport", Label = "Los Santos Airport", Coords = vector3(-1037.7, -2737.8, 20.2), }, { Id = "vinewood", Label = "Vinewood", Coords = vector3(-594.4, -929.9, 23.9), }, }, } Config.Crypto = { Enabled = true, Currency = "$", BankAccount = "bank", AssetScale = 1000000, PriceScale = 100, QuoteLifetimeSeconds = 8, PriceTickMinimumSeconds = 7, PriceTickMaximumSeconds = 12, MarketsPerTickMinimum = 8, MarketsPerTickMaximum = 12, TickMovementDivisor = 10, RandomImpulseDivisor = 3, MomentumDecayBasisPoints = 8000, MomentumImpulseBasisPoints = 2000, MeanReversionBasisPoints = 55, CycleDurationMinimumTicks = 14, CycleDurationMaximumTicks = 30, CycleStrengthMinimumBasisPoints = 2800, CycleStrengthMaximumBasisPoints = 5200, CycleTransitionBasisPoints = 1800, GlobalCycleMinimumTicks = 24, GlobalCycleMaximumTicks = 54, GlobalTrendMinimumBasisPoints = 8, GlobalTrendMaximumBasisPoints = 24, MarketShockChanceBasisPoints = 100, MarketShockMinimumMultiplier = 2, MarketShockMaximumMultiplier = 3, MaximumMovementMultiplier = 3, HistoryRetentionTicks = 4096, SparklinePoints = 48, SessionSeconds = 30 * 60, RecentAuthenticationSeconds = 5 * 60, PasswordMinLength = 8, PasswordMaxLength = 72, HandleMinLength = 3, HandleMaxLength = 20, FeeBasisPoints = 75, MinimumFee = 1, MinimumSettlement = 10, MaximumSettlement = 250000, MaximumTradeNotional = 100000, MaximumPositionQuantity = 100000, MaximumTransferQuantity = 100000, DailyDepositLimit = 500000, DailyWithdrawalLimit = 250000, DailyTradeLimit = 500000, ActionsPerMinute = 30, LoginAttempts = 5, LockoutSeconds = 5 * 60, TreasuryCash = 5000000, Markets = { { Id = "aurora", Symbol = "AUR", Name = "Aurora", Color = "#25d9ad", Logo = "◈", InitialPrice = 12850, MinimumPrice = 3000, MaximumPrice = 80000, VolatilityBasisPoints = 180, IssuedSupply = 1000000, TreasuryInventory = 850000, }, { Id = "vertex", Symbol = "VTX", Name = "Vertex", Color = "#4d8cff", Logo = "◆", InitialPrice = 4275, MinimumPrice = 800, MaximumPrice = 30000, VolatilityBasisPoints = 260, IssuedSupply = 2500000, TreasuryInventory = 2100000, }, { Id = "ember", Symbol = "EMB", Name = "Ember", Color = "#ff9d54", Logo = "✦", InitialPrice = 980, MinimumPrice = 100, MaximumPrice = 12000, VolatilityBasisPoints = 340, IssuedSupply = 8000000, TreasuryInventory = 6800000, }, { Id = "titan", Symbol = "TTN", Name = "Titan", Color = "#8f7cff", Logo = "⬢", InitialPrice = 425000000, MinimumPrice = 100000000, MaximumPrice = 900000000, VolatilityBasisPoints = 65, IssuedSupply = 21000, TreasuryInventory = 17500, }, { Id = "crown", Symbol = "CRN", Name = "Crown", Color = "#f6c453", Logo = "♛", InitialPrice = 128000000, MinimumPrice = 25000000, MaximumPrice = 350000000, VolatilityBasisPoints = 85, IssuedSupply = 64000, TreasuryInventory = 51000, }, { Id = "atlas", Symbol = "ATL", Name = "Atlas", Color = "#e66f9e", Logo = "▲", InitialPrice = 12000000, MinimumPrice = 3000000, MaximumPrice = 30000000, VolatilityBasisPoints = 110, IssuedSupply = 250000, TreasuryInventory = 205000, }, { Id = "zenith", Symbol = "ZNT", Name = "Zenith", Color = "#6b8cff", Logo = "✥", InitialPrice = 68000000, MinimumPrice = 18000000, MaximumPrice = 160000000, VolatilityBasisPoints = 95, IssuedSupply = 125000, TreasuryInventory = 99000, }, { Id = "celestium", Symbol = "CLS", Name = "Celestium", Color = "#8ad8ff", Logo = "✧", InitialPrice = 8450000, MinimumPrice = 1500000, MaximumPrice = 22000000, VolatilityBasisPoints = 125, IssuedSupply = 420000, TreasuryInventory = 340000, }, { Id = "orbit", Symbol = "ORB", Name = "Orbit", Color = "#57c7ff", Logo = "◎", InitialPrice = 1244000, MinimumPrice = 250000, MaximumPrice = 3500000, VolatilityBasisPoints = 145, IssuedSupply = 900000, TreasuryInventory = 735000, }, { Id = "helix", Symbol = "HLX", Name = "Helix", Color = "#c47cff", Logo = "⌁", InitialPrice = 582000, MinimumPrice = 90000, MaximumPrice = 1600000, VolatilityBasisPoints = 175, IssuedSupply = 1400000, TreasuryInventory = 1140000, }, { Id = "nova", Symbol = "NVA", Name = "Nova", Color = "#ff6f91", Logo = "✺", InitialPrice = 325000, MinimumPrice = 50000, MaximumPrice = 900000, VolatilityBasisPoints = 210, IssuedSupply = 2200000, TreasuryInventory = 1800000, }, { Id = "prism", Symbol = "PRM", Name = "Prism", Color = "#5ee1c4", Logo = "◇", InitialPrice = 74500, MinimumPrice = 12000, MaximumPrice = 240000, VolatilityBasisPoints = 195, IssuedSupply = 3800000, TreasuryInventory = 3100000, }, { Id = "quantum", Symbol = "QTM", Name = "Quantum", Color = "#7a9cff", Logo = "◉", InitialPrice = 21400, MinimumPrice = 3500, MaximumPrice = 85000, VolatilityBasisPoints = 230, IssuedSupply = 5200000, TreasuryInventory = 4250000, }, { Id = "drift", Symbol = "DRF", Name = "Drift", Color = "#4ecdc4", Logo = "≋", InitialPrice = 7600, MinimumPrice = 900, MaximumPrice = 30000, VolatilityBasisPoints = 280, IssuedSupply = 12000000, TreasuryInventory = 9800000, }, { Id = "pulse", Symbol = "PLS", Name = "Pulse", Color = "#ff5f7f", Logo = "◍", InitialPrice = 1840, MinimumPrice = 200, MaximumPrice = 9000, VolatilityBasisPoints = 320, IssuedSupply = 18000000, TreasuryInventory = 14800000, }, { Id = "moss", Symbol = "MOS", Name = "Moss", Color = "#64c987", Logo = "♧", InitialPrice = 460, MinimumPrice = 60, MaximumPrice = 2400, VolatilityBasisPoints = 360, IssuedSupply = 36000000, TreasuryInventory = 29500000, }, { Id = "flux", Symbol = "FLX", Name = "Flux", Color = "#a777e3", Logo = "ϟ", InitialPrice = 238, MinimumPrice = 35, MaximumPrice = 1400, VolatilityBasisPoints = 390, IssuedSupply = 44000000, TreasuryInventory = 36000000, }, { Id = "tide", Symbol = "TDE", Name = "Tide", Color = "#46a6ff", Logo = "≈", InitialPrice = 125, MinimumPrice = 20, MaximumPrice = 700, VolatilityBasisPoints = 410, IssuedSupply = 60000000, TreasuryInventory = 49000000, }, { Id = "spark", Symbol = "SPK", Name = "Spark", Color = "#ffb84d", Logo = "✹", InitialPrice = 74, MinimumPrice = 12, MaximumPrice = 420, VolatilityBasisPoints = 430, IssuedSupply = 85000000, TreasuryInventory = 70000000, }, { Id = "pebble", Symbol = "PBL", Name = "Pebble", Color = "#9aa8b8", Logo = "●", InitialPrice = 22, MinimumPrice = 4, MaximumPrice = 160, VolatilityBasisPoints = 470, IssuedSupply = 150000000, TreasuryInventory = 124000000, }, { Id = "nano", Symbol = "NNO", Name = "Nano", Color = "#5bd6ff", Logo = "η", InitialPrice = 9, MinimumPrice = 1, MaximumPrice = 85, VolatilityBasisPoints = 520, IssuedSupply = 260000000, TreasuryInventory = 214000000, }, { Id = "shard", Symbol = "SHD", Name = "Shard", Color = "#70e0d0", Logo = "△", InitialPrice = 5, MinimumPrice = 1, MaximumPrice = 55, VolatilityBasisPoints = 560, IssuedSupply = 420000000, TreasuryInventory = 345000000, }, { Id = "pixel", Symbol = "PXL", Name = "Pixel", Color = "#ff78c8", Logo = "▦", InitialPrice = 3, MinimumPrice = 1, MaximumPrice = 32, VolatilityBasisPoints = 610, IssuedSupply = 700000000, TreasuryInventory = 580000000, }, { Id = "dust", Symbol = "DST", Name = "Dust", Color = "#c4b5a5", Logo = "·", InitialPrice = 1, MinimumPrice = 1, MaximumPrice = 18, VolatilityBasisPoints = 680, IssuedSupply = 1200000000, TreasuryInventory = 990000000, }, }, } -- ============================================================================= -- Server-only configuration -- ============================================================================= if IsDuplicityVersion() then -- ------------------------------------------------------------------------- -- Server secrets -- ------------------------------------------------------------------------- Config.Server = { -- Keep these values private and stable. Changing a pepper invalidates existing app passwords. PasscodePepper = "f626581802800478346266e66414d8e6f2c28050214a593c25901904c162bffe", CrewLinkPasswordPepper = "2751e5729aee4955a529c1a87104b58fbe1d7280b18b66264236028caa06eb47", FlipTokPasswordPepper = "a85ea307680f1205a4fda03be8af18ecf7edf16ffc83450b90cac7e41a9719a7", PicstagramPasswordPepper = "653e41dd19aba5ef750a668ad1886273ba7d0e0420bd5c745748df80a6e22676", } -- ------------------------------------------------------------------------- -- Company directory -- ------------------------------------------------------------------------- Config.Companies = { Enabled = true, PageSize = 20, MaximumPageSize = 50, MaximumOpenRequestsPerSim = 5, MaximumServices = 25, MaximumRequestMedia = 3, SubjectMaxLength = 120, RequestBodyMaxLength = 2000, MessageMaxLength = 2000, ProfileDescriptionMaxLength = 1000, DistrictMaxLength = 80, AddressMaxLength = 160, ServiceTitleMaxLength = 80, ServiceDescriptionMaxLength = 500, ServicePriceMaxLength = 80, AnnouncementTitleMaxLength = 120, AnnouncementBodyMaxLength = 1000, AvailabilityMaximumSeconds = 24 * 60 * 60, AnnouncementMaximumSeconds = 30 * 24 * 60 * 60, RetentionDays = 180, RateLimits = { Read = 120, Search = 60, CreateRequest = 5, Message = 30, RequestAction = 30, Profile = 12, CallAvailability = 30, }, CallRouting = { MaxAttempts = 3, RingSeconds = 10, }, Categories = { "public_services", "vehicles", "transport", }, Statuses = { new = true, assigned = true, in_progress = true, waiting_customer = true, completed = true, cancelled = true, }, AvailabilityStatuses = { available = true, busy = true, closed = true, }, Definitions = { police = { Job = "police", Name = "Los Santos Police Department", Category = "public_services", Public = true, Emergency = true, Verified = true, Icon = "shield", LogoUrl = "https://picsum.photos/seed/companies-police-logo/180/180", Description = "Public safety, emergency response, and police services.", DefaultAvailability = "closed", AcceptsRequests = true, District = "Mission Row", LocationLabel = "Mission Row Police Station", Address = "Mission Row Police Station", Location = vector3(425.1, -979.5, 30.7), ServiceLine = { Number = "911", AutoContact = true, CanCall = true, CanMessage = true, Routing = "round_robin", MinimumGrade = 0, }, Permissions = { WorkQueue = 0, Availability = 1, Assign = 2, Profile = 3, Hours = 3, Services = 3, Announcement = 3, }, Services = { { Id = "police-assistance", Title = "Police assistance", Description = "Request non-emergency police assistance.", Price = "", RequestsEnabled = true, }, }, }, ambulance = { Job = "ambulance", Name = "Emergency Medical Services", Category = "public_services", Public = true, Emergency = true, Verified = true, Icon = "medical", LogoUrl = "https://picsum.photos/seed/companies-ems-logo/180/180", Description = "Emergency medical response and patient care.", DefaultAvailability = "closed", AcceptsRequests = false, District = "Pillbox Hill", LocationLabel = "Pillbox Hill Medical Center", Address = "Pillbox Hill Medical Center", Location = vector3(307.2, -595.3, 43.3), ServiceLine = { Number = "912", AutoContact = true, CanCall = true, CanMessage = false, Routing = "round_robin", MinimumGrade = 0, }, Permissions = { WorkQueue = 0, Availability = 1, Assign = 2, Profile = 3, Hours = 3, Services = 3, Announcement = 3, }, Services = {}, }, fire = { Job = "fire", Name = "Los Santos Fire Department", Category = "public_services", Public = true, Emergency = true, Verified = true, Icon = "flame", LogoUrl = "https://picsum.photos/seed/companies-fire-logo/180/180", Description = "Fire response, rescue, and public safety services.", DefaultAvailability = "closed", AcceptsRequests = false, District = "El Burro Heights", LocationLabel = "Capital Boulevard Fire Station", Address = "Capital Boulevard Fire Station", Location = vector3(1200.6, -1473.6, 34.9), ServiceLine = { Number = "913", AutoContact = true, CanCall = true, CanMessage = false, Routing = "round_robin", MinimumGrade = 0, }, Permissions = { WorkQueue = 0, Availability = 1, Assign = 2, Profile = 3, Hours = 3, Services = 3, Announcement = 3, }, Services = {}, }, mechanic = { Job = "mechanic", Name = "Los Santos Customs", Category = "vehicles", Public = true, Emergency = false, Verified = true, Icon = "wrench", LogoUrl = "https://picsum.photos/seed/companies-mechanic-logo/180/180", Description = "Vehicle diagnostics, repairs, and roadside assistance.", DefaultAvailability = "closed", AcceptsRequests = true, District = "Burton", LocationLabel = "Los Santos Customs", Address = "Carcer Way", Location = vector3(-337.3, -136.9, 39.0), ServiceLine = { Number = "5550101000", AutoContact = true, CanCall = true, CanMessage = false, Routing = "round_robin", MinimumGrade = 0, }, Permissions = { WorkQueue = 0, Availability = 1, Assign = 2, Profile = 3, Hours = 3, Services = 3, Announcement = 3, }, Services = { { Id = "mechanic-repair", Title = "Vehicle repair", Description = "Diagnostics and repairs for road vehicles.", Price = "Price after inspection", RequestsEnabled = true, }, { Id = "mechanic-towing", Title = "Roadside assistance", Description = "Assistance for disabled vehicles.", Price = "Price by distance", RequestsEnabled = true, }, }, }, taxi = { Job = "taxi", Name = "Downtown Cab Co.", Category = "transport", Public = true, Emergency = false, Verified = true, Icon = "car", LogoUrl = "https://picsum.photos/seed/companies-taxi-logo/180/180", Description = "Staffed taxi rides throughout Los Santos and Blaine County.", DefaultAvailability = "closed", AcceptsRequests = true, District = "East Vinewood", LocationLabel = "Downtown Cab Co.", Address = "Tangerine Street", Location = vector3(895.0, -179.2, 74.7), ServiceLine = { Number = "5550102000", AutoContact = true, CanCall = true, CanMessage = false, Routing = "round_robin", MinimumGrade = 0, }, Permissions = { WorkQueue = 0, Availability = 1, Assign = 2, Profile = 3, Hours = 3, Services = 3, Announcement = 3, }, Services = { { Id = "taxi-ride", Title = "Taxi ride", Description = "Request a staffed taxi service.", Price = "Metered fare", RequestsEnabled = true, }, }, }, }, } -- ------------------------------------------------------------------------- -- Music library -- ------------------------------------------------------------------------- Config.Music = { -- Files are found recursively in config/music by their Id. For example, -- Id = "night-drive" finds night-drive.ogg/mp3 and optional artwork with -- the same name (.webp/.png/.jpg/.jpeg), even inside subdirectories. Tracks = { -- { -- Id = "night-drive", -- Title = "Night Drive", -- Artist = "Sky Records", -- }, }, MaximumPersonalSongs = 100, MaximumPlaylists = 50, MaximumPlaylistSongs = 250, PlaylistNameMaxLength = 80, ActionsPerMinute = 30, MetadataTimeoutMs = 4500, } -- ------------------------------------------------------------------------- -- Weazel News -- ------------------------------------------------------------------------- Config.WeazelNews = { Enabled = true, PageSize = 20, MaximumOffset = 10000, MaximumImages = 6, SearchMaxLength = 80, DraftTitleMinLength = 1, DraftBodyMinLength = 1, TitleMinLength = 1, TitleMaxLength = 160, BodyMinLength = 1, BodyMaxLength = 12000, ExcerptMaxLength = 240, RateLimits = { Read = 120, Write = 20, }, Categories = { "official", "events", "jobs", "news", "business", }, -- Framework job name = minimum grade. Every listed job can manage every article. AllowedJobs = { weazel = 0, reporter = 0, }, } -- ------------------------------------------------------------------------- -- CityWarn population warnings -- ------------------------------------------------------------------------- Config.CityWarn = { Enabled = true, PageSize = 30, MaximumActiveAlerts = 20, TitleMaxLength = 120, BodyMaxLength = 2000, InstructionsMaxLength = 2000, UpdateMaxLength = 2000, AreaLabelMaxLength = 120, MinimumRadius = 100, MaximumRadius = 10000, DefaultDurationMinutes = 60, MaximumDurationMinutes = 1440, RequireDuty = true, RateLimits = { Read = 180, Write = 20, }, Publishers = { police = { MinimumGrade = 2, MaximumSeverity = "extreme", CityWide = true, Categories = { "public_safety", "police", "infrastructure", "evacuation" }, }, fire = { MinimumGrade = 2, MaximumSeverity = "extreme", CityWide = true, Categories = { "public_safety", "fire", "infrastructure", "evacuation" }, }, ambulance = { MinimumGrade = 2, MaximumSeverity = "danger", CityWide = false, Categories = { "public_safety", "medical", "evacuation" }, }, government = { MinimumGrade = 2, MaximumSeverity = "extreme", CityWide = true, Categories = { "public_safety", "police", "fire", "medical", "infrastructure", "evacuation" }, }, }, } -- ------------------------------------------------------------------------- -- Database migrations -- ------------------------------------------------------------------------- Config.Migrations = Config.Migrations or {} -- Manual, non-destructive import from LB Phone's `phone_*` database tables. -- The migration never starts during a resource/server restart. Completed -- domains are recorded in `sky_phone_migrations` for idempotent retries. -- Import: skyphone:migrate lb-phone -- Console preview: skyphone:migrate lb-phone dry -- Idempotent retry: skyphone:migrate lb-phone force -- Remove imported Sky data: skyphone:migrate lb-phone remove Config.Migrations.LbPhone = { SourcePrefix = "phone_", -- auto: direct framework identifier first, then an unambiguous license match. -- identifier: only match phone_phones.owner_id to the framework identifier. -- license: only resolve phone_phones.owner_id through the framework license. IdentifierMode = "auto", Domains = { devices = true, settings = true, alarms = true, contacts = true, blocked = true, calls = true, messages = true, photos = true, notes = true, wallet = true, voiceMemos = true, picstagram = true, mail = true, mapMarkers = true, darkChat = true, flipTok = true, feather = true, flare = true, }, } end --[[ Sky Phone media configuration This file is loaded on the server only. Keep API keys private. When the phone configurator is enabled in config.lua, the active media configuration is loaded from SQL and frontend builds copy the shipped values from this file into source/shared/config_default.lua. ]] Config.Media = { -- Create or sign in to an account at https://developers.giphy.com/, open -- the Developer Dashboard, choose "Create an API Key", and paste it here. GiphyApiKey = "", GifPageSize = 24, GifRating = "pg-13", UrlMaxLength = 2048, AllowedGifHosts = { "giphy.com" }, -- Create or sign in at https://fivemanage.com/, create or select your team, -- then open Dashboard > Tokens and create a token with Media access. Keep -- this server-only token private and paste it here. FiveManage = { ApiKey = "", BaseUrl = "https://api.fivemanage.com/api/v3/file", RequestTimeoutMs = 10000, UploadTimeoutMs = 25000, }, Import = { Enabled = true, PageSize = 30, MaxSelection = 10, MaxPhotoBytes = 15 * 1024 * 1024, MaxVideoBytes = 150 * 1024 * 1024, RevalidateAfterSeconds = 3600, ListActionsPerMinute = 60, ImportActionsPerMinute = 20, CandidateTtlSeconds = 300, ManifestCacheSeconds = 30, ManifestMaxBytes = 2 * 1024 * 1024, ManifestMaxItems = 5000, Websites = { { Id = "fivemanage", Label = "FiveManage", Enabled = true, Adapter = "fivemanage", Path = "sky_phone/imports", MediaTypes = { "photo", "video" }, -- Direct Gallery links must use one of these hosts or a subdomain. AllowedMediaHosts = { "fivemanage.com" }, }, --[[ { Id = "city_media", Label = "City Media", Enabled = true, Adapter = "manifest", ManifestUrl = "https://media.example.com/sky-phone/media.json", MediaTypes = { "photo", "video" }, AllowedMediaHosts = { "media.example.com", "cdn.example.com" }, Auth = { Type = "bearer", TokenConvar = "sky_phone_city_media_token", }, RequiredAce = "sky_phone.import.city_media", }, ]] }, }, Wallpaper = { -- Shows the verified HTTPS media import directly in the wallpaper picker. -- Camera and Photos wallpaper sources are not affected by this setting. CustomUploadEnabled = true, }, Photo = { Encoding = "jpg", Quality = 0.95, }, Video = { BitrateKbps = 1500, }, UploadSessionTimeoutMs = 60000, PageSize = 30, } ConfigDefaults = Config Config = realConfig