198 lines
11 KiB
JavaScript
198 lines
11 KiB
JavaScript
"use strict";
|
|
|
|
const APP_VERSION = "39.18.11";
|
|
const CACHE_NAME = `tarinai-colony-${APP_VERSION}`;
|
|
const v = `v=${APP_VERSION}`;
|
|
// Static runtime list synchronized with app_manifest.json for this release.
|
|
const coreScriptNames = [
|
|
"version", "event_bus", "domain_ids", "registry_base", "disease_registry", "sound_pack", "deterministic_helpers", "item_tool_metadata", "item_tool_definitions", "item_visual_definitions", "item_food_definitions", "item_effect_definitions", "item_registry", "data", "ground_types", "input_mode_manager", "math", "geometry_helpers", "collision_footprint_system", "physics_helpers", "placement_preview_system", "pin_attachment_system", "physics_shape_editor_system", "mechanical_system", "mechanical_shape_bridge", "constraint_system", "physics_world_system", "physics_projection_system", "circuit_board_system", "signal_system", "assets", "audio", "perf_profiler", "display_helpers", "render", "sim_core", "tarinai_seed_factory", "structures", "item_type_catalog", "items", "item_type_initializers", "item_lifecycle_support", "item_update_policy", "fire_runtime_system", "robot_cleaner_system", "item_dynamic_tool_system", "item_dynamic_ball_system", "item_dynamic_duplicator_system", "item_dynamic_pin_system", "item_dynamic_zunchi_system", "item_environment_hazard_system", "item_dynamic_system", "item_lifecycle_decay_system", "item_lifecycle_growth_system", "item_lifecycle_step_frame", "item_lifecycle_step_decay", "item_lifecycle_step_dynamic", "item_lifecycle_step_growth", "update_step_pipeline_runner", "item_lifecycle_pipeline", "item_runtime", "structure_lifecycle", "memorial_bell_system", "item_render_helpers", "item_render_runtime", "burn_motion_util", "ants", "health", "tarinai", "tarinai_action_spec", "tarinai_behavior_state", "tarinai_identity_social", "tarinai_action_state", "tarinai_disease_nest", "tarinai_item_effects", "tarinai_needs_core", "tarinai_behavior_text", "tarinai_forced_behavior", "tarinai_nest_sleep_system", "tarinai_item_targeting", "tarinai_consumable_behavior", "tarinai_social_action_runtime", "tarinai_building_behavior", "seesaw_system", "tarinai_action_definitions", "tarinai_needs_items", "tarinai_food_prototype_mixin", "tarinai_direct_feeding_system", "tarinai_need_planner_system", "tarinai_item_interaction_context", "tarinai_food_interaction_system", "tarinai_contact_item_system", "tarinai_item_interaction_system", "tarinai_sunbath_system", "tarinai_cursor_care_system", "tarinai_local_environment_system", "tarinai_social_move_life", "tarinai_update_step_frame", "tarinai_update_step_ai", "tarinai_update_step_environment", "tarinai_update_step_movement", "tarinai_update_step_health", "tarinai_update_pipeline", "tarinai_runtime", "tarinai_render", "world", "world_view", "family_graph", "world_reset_presets", "world_family_social", "impact_core_system", "impact_response_system", "collision_response_system", "world_combat_effects", "world_environment", "world_temperature_system", "world_pathfinding_system", "world_grass_placement_system", "world_spatial_budget", "world_ants_system", "weather_system", "item_update_scheduler", "simulation_runtime_helpers", "tarinai_update_policy", "simulation_environment_system", "simulation_item_ant_system", "simulation_effects_system", "simulation_creature_system", "simulation_maintenance_system", "simulation_ambient_system", "simulation_systems", "system_order", "simulation", "colony_situation_system", "world_update", "world_tool_actions", "world_placement_log", "world_event_effects", "command_dispatcher", "text_catalog", "ui", "game_dialogs", "achievement_catalog", "achievements", "ui_helpers", "ui_log", "ui_selected", "save_schema", "snapshot_system", "restore_coordinator", "history_system", "save_codec", "save_storage", "save_system", "ui_tooltips", "ui_layout_dialogs", "ui_ground", "ui_tools", "ui_input_shared", "ui_pointer_action_system", "ui_input_touch", "ui_input_mouse", "ui_bind", "ui_charts", "ui_family_data", "ui_family_async", "ui_family_layout", "ui_family_paths", "ui_family_render", "main", "debug_tools"
|
|
];
|
|
const mediaAssetNames = [
|
|
"assets/objects/ant_queen.webp",
|
|
"assets/objects/ant_worker.webp",
|
|
"assets/objects/genkotsu.webp",
|
|
"assets/objects/oshibyo.webp",
|
|
"assets/objects/oshibyo_stuck.webp",
|
|
"assets/objects/plushie_bear.png",
|
|
"assets/objects/pushpin.webp",
|
|
"assets/objects/pushpin_stuck.webp",
|
|
"assets/objects/zunchi.webp",
|
|
"assets/objects/zunchi_02.webp",
|
|
"assets/sounds/achievement_unlock.mp3",
|
|
"assets/sounds/acquired_stress_001.wav",
|
|
"assets/sounds/acquired_stress_002.wav",
|
|
"assets/sounds/acquired_stress_003.wav",
|
|
"assets/sounds/acquired_stress_004.wav",
|
|
"assets/sounds/acquired_stress_005.wav",
|
|
"assets/sounds/acquired_stress_006.wav",
|
|
"assets/sounds/bicycle_bell.mp3",
|
|
"assets/sounds/firecracker_explosion.mp3",
|
|
"assets/sounds/major_damage_01.wav",
|
|
"assets/sounds/major_damage_02.wav",
|
|
"assets/sounds/major_damage_03.wav",
|
|
"assets/sounds/major_damage_04.wav",
|
|
"assets/sounds/shoot_bolt_action.mp3",
|
|
"assets/sounds/shoot_pistol.mp3",
|
|
"assets/sounds/voice_001_hau.wav",
|
|
"assets/sounds/voice_002_flee.wav",
|
|
"assets/sounds/voice_003_po.wav",
|
|
"assets/sounds/voice_004_eat.wav",
|
|
"assets/sounds/voice_005_stress.wav",
|
|
"assets/sounds/voice_006_sleep.wav",
|
|
"assets/sounds/voice_007_sunbath_pokapoka.wav",
|
|
"assets/sounds/voice_008_temperature_buruburu.wav",
|
|
"assets/sounds/voice_009_temperature_achui.wav",
|
|
"assets/sprites/tarinai_01_smile.webp",
|
|
"assets/sprites/tarinai_02_angry.webp",
|
|
"assets/sprites/tarinai_03_teary.webp",
|
|
"assets/sprites/tarinai_04_jito.webp",
|
|
"assets/sprites/tarinai_05_drool.webp",
|
|
"assets/sprites/tarinai_06_cry.webp",
|
|
"assets/sprites/tarinai_07_sleep.webp",
|
|
"assets/sprites/tarinai_08_pokan.webp",
|
|
"assets/sprites/tarinai_09_stretch.webp",
|
|
"assets/sprites/tarinai_10_hurt.webp",
|
|
"assets/sprites/tarinai_11_weak.webp",
|
|
"assets/sprites/tarinai_12_back.webp",
|
|
"assets/sprites/tarinai_13_flee.webp",
|
|
"assets/sprites/tarinai_14_zunda_eat.webp",
|
|
"assets/sprites/tarinai_15_hurt2.webp",
|
|
"assets/sprites/tarinai_16_normal_smirk.webp",
|
|
"assets/sprites/tarinai_17_normal_tongue.webp",
|
|
"assets/sprites/tarinai_18_fear.webp",
|
|
"assets/sprites/tarinai_19_flee_fear2.webp",
|
|
"assets/sprites/tarinai_20_sleep2.webp",
|
|
"assets/sprites/tarinai_21_normal_happy.webp",
|
|
"assets/sprites/tarinai_22_fear_blue.webp",
|
|
"assets/sprites/tarinai_23_fear_cry.webp",
|
|
"assets/sprites/tarinai_24_stress_dizzy.webp",
|
|
"assets/sprites/tarinai_25_stress_sweat.webp",
|
|
"assets/sprites/tarinai_26_intimidate.webp",
|
|
"assets/sprites/tarinai_27_birth_ritual.webp",
|
|
"assets/sprites/tarinai_28_zunchi_slave.webp",
|
|
"assets/sprites/tarinai_29_hungry_70.webp",
|
|
"assets/sprites/tarinai_30_zunchi_slave_alt.webp",
|
|
"assets/sprites/tarinai_31_sunbath_01.webp",
|
|
"assets/sprites/tarinai_32_sunbath_02.webp",
|
|
"assets/sprites/tarinai_33_sunbath_03.webp",
|
|
"assets/sprites/tarinai_34_hot_01.webp",
|
|
"assets/sprites/tarinai_35_hot_02.webp",
|
|
"assets/sprites/tarinai_36_hot_03.webp",
|
|
"assets/sprites/tarinai_37_cold_01.webp",
|
|
"assets/sprites/tarinai_38_cold_02.webp",
|
|
"assets/sprites/tarinai_39_cold_03.webp",
|
|
"assets/sprites/tarinai_acquired_overlay.png",
|
|
"assets/ui/apple-touch-icon.png",
|
|
"assets/ui/ecology_hp_stress.webp",
|
|
"assets/ui/favicon.png",
|
|
"assets/ui/tool_acquired_tarinai.webp",
|
|
"assets/ui/tool_ammo.webp",
|
|
"assets/ui/tool_ant_nest.webp",
|
|
"assets/ui/tool_ball.webp",
|
|
"assets/ui/tool_bed.webp",
|
|
"assets/ui/tool_delete.webp",
|
|
"assets/ui/tool_duplicator.webp",
|
|
"assets/ui/tool_dwarf_drug.webp",
|
|
"assets/ui/tool_fence_h.webp",
|
|
"assets/ui/tool_fence_v.webp",
|
|
"assets/ui/tool_fight_mochi.webp",
|
|
"assets/ui/tool_firecracker.webp",
|
|
"assets/ui/tool_genkotsu.webp",
|
|
"assets/ui/tool_giant_drug.webp",
|
|
"assets/ui/tool_grass.webp",
|
|
"assets/ui/tool_laxative.webp",
|
|
"assets/ui/tool_love_mochi.webp",
|
|
"assets/ui/tool_mercury.webp",
|
|
"assets/ui/tool_mystery_drug.webp",
|
|
"assets/ui/tool_nest_box.webp",
|
|
"assets/ui/tool_new.webp",
|
|
"assets/ui/tool_niteropu.webp",
|
|
"assets/ui/tool_observe.webp",
|
|
"assets/ui/tool_oshibyo.webp",
|
|
"assets/ui/tool_protein.webp",
|
|
"assets/ui/tool_pushpin.webp",
|
|
"assets/ui/tool_shoot.png",
|
|
"assets/ui/tool_signboard.webp",
|
|
"assets/ui/tool_sleep_drug.webp",
|
|
"assets/ui/tool_stone.webp",
|
|
"assets/ui/tool_sweet.webp",
|
|
"assets/ui/tool_zunchi.webp",
|
|
"assets/ui/tool_zunda_juice.webp"
|
|
];
|
|
const CORE_ASSETS = [
|
|
"./",
|
|
"./index.html",
|
|
`./css/base.css?${v}`,
|
|
`./css/layout.css?${v}`,
|
|
`./css/panel.css?${v}`,
|
|
`./css/components.css?${v}`,
|
|
`./css/mobile.css?${v}`,
|
|
...coreScriptNames.map(name => `./js/${name}.js?${v}`),
|
|
"./app_manifest.json",
|
|
"./manifest.webmanifest",
|
|
"./favicon.ico",
|
|
"./assets/ui/pwa-icon-192.png",
|
|
"./assets/ui/pwa-icon-512.png",
|
|
...mediaAssetNames.map(name => `./${name}`),
|
|
];
|
|
|
|
self.addEventListener("install", event => {
|
|
event.waitUntil((async () => {
|
|
const cache = await caches.open(CACHE_NAME);
|
|
await cache.addAll(CORE_ASSETS);
|
|
await self.skipWaiting();
|
|
})());
|
|
});
|
|
|
|
self.addEventListener("activate", event => {
|
|
event.waitUntil((async () => {
|
|
const keys = await caches.keys();
|
|
await Promise.all(keys
|
|
.filter(key => key.startsWith("tarinai-colony-") && key !== CACHE_NAME)
|
|
.map(key => caches.delete(key)));
|
|
await self.clients.claim();
|
|
})());
|
|
});
|
|
|
|
function isStaticAsset(request) {
|
|
return /\.(?:js|css|json|webmanifest|ico|webp|png|jpg|jpeg|gif|svg|mp3|wav|woff2?)$/i.test(new URL(request.url).pathname);
|
|
}
|
|
function cacheableResponse(response) {
|
|
return response && response.status === 200 && response.type !== "opaque";
|
|
}
|
|
function putCacheSafely(request, response) {
|
|
if (!cacheableResponse(response)) return Promise.resolve(false);
|
|
return caches.open(CACHE_NAME).then(cache => cache.put(request, response.clone())).then(() => true).catch(() => false);
|
|
}
|
|
|
|
self.addEventListener("fetch", event => {
|
|
const request = event.request;
|
|
if (request.method !== "GET") return;
|
|
const url = new URL(request.url);
|
|
// PWA-04 intentionally remains unchanged: cross-origin Google Fonts are not cached.
|
|
if (url.origin !== self.location.origin || /service-worker\.js$/i.test(url.pathname)) return;
|
|
if (request.mode === "navigate" || /index\.html$/i.test(url.pathname)) {
|
|
const networkResponse = fetch(request);
|
|
const cacheWrite = networkResponse.then(response => putCacheSafely(request, response)).catch(() => false);
|
|
event.waitUntil(cacheWrite.then(() => undefined));
|
|
event.respondWith(networkResponse.catch(() => caches.match(request).then(cached => cached || caches.match("./index.html"))));
|
|
return;
|
|
}
|
|
if (isStaticAsset(request)) {
|
|
const responsePromise = caches.match(request).then(async cached => {
|
|
if (cached) return cached;
|
|
// Media are precached at their canonical URL. JS/CSS query versions must not
|
|
// resolve to an older cached file, otherwise UI fixes can remain stale.
|
|
const isCodeAsset = /\.(?:js|css)$/i.test(url.pathname);
|
|
if (!isCodeAsset) {
|
|
const canonical = await caches.match(request, { ignoreSearch: true });
|
|
if (canonical) return canonical;
|
|
}
|
|
const response = await fetch(request);
|
|
await putCacheSafely(request, response);
|
|
return response;
|
|
});
|
|
event.waitUntil(responsePromise.then(() => undefined, () => undefined));
|
|
event.respondWith(responsePromise);
|
|
}
|
|
});
|