@jjlmoya/utils-games-development 1.50.0 → 1.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/package.json +1 -1
  2. package/src/category/index.ts +3 -1
  3. package/src/entries.ts +8 -1
  4. package/src/tests/locale_completeness.test.ts +2 -2
  5. package/src/tests/tool_validation.test.ts +2 -2
  6. package/src/tool/audioLoopPointFinder/audio-loop-point-finder.css +322 -0
  7. package/src/tool/audioLoopPointFinder/audio-player.ts +84 -0
  8. package/src/tool/audioLoopPointFinder/bibliography.astro +6 -0
  9. package/src/tool/audioLoopPointFinder/bibliography.ts +16 -0
  10. package/src/tool/audioLoopPointFinder/client.ts +262 -0
  11. package/src/tool/audioLoopPointFinder/component.astro +147 -0
  12. package/src/tool/audioLoopPointFinder/dom-utils.ts +55 -0
  13. package/src/tool/audioLoopPointFinder/entry.ts +27 -0
  14. package/src/tool/audioLoopPointFinder/i18n/de.ts +211 -0
  15. package/src/tool/audioLoopPointFinder/i18n/en.ts +211 -0
  16. package/src/tool/audioLoopPointFinder/i18n/es.ts +211 -0
  17. package/src/tool/audioLoopPointFinder/i18n/fr.ts +211 -0
  18. package/src/tool/audioLoopPointFinder/i18n/id.ts +211 -0
  19. package/src/tool/audioLoopPointFinder/i18n/it.ts +211 -0
  20. package/src/tool/audioLoopPointFinder/i18n/ja.ts +211 -0
  21. package/src/tool/audioLoopPointFinder/i18n/ko.ts +211 -0
  22. package/src/tool/audioLoopPointFinder/i18n/nl.ts +211 -0
  23. package/src/tool/audioLoopPointFinder/i18n/pl.ts +211 -0
  24. package/src/tool/audioLoopPointFinder/i18n/pt.ts +211 -0
  25. package/src/tool/audioLoopPointFinder/i18n/ru.ts +211 -0
  26. package/src/tool/audioLoopPointFinder/i18n/sv.ts +211 -0
  27. package/src/tool/audioLoopPointFinder/i18n/tr.ts +211 -0
  28. package/src/tool/audioLoopPointFinder/i18n/zh.ts +211 -0
  29. package/src/tool/audioLoopPointFinder/index.ts +11 -0
  30. package/src/tool/audioLoopPointFinder/logic.test.ts +72 -0
  31. package/src/tool/audioLoopPointFinder/logic.ts +214 -0
  32. package/src/tool/audioLoopPointFinder/metadata-parser.ts +94 -0
  33. package/src/tool/audioLoopPointFinder/seo.astro +15 -0
  34. package/src/tool/audioLoopPointFinder/ui.ts +42 -0
  35. package/src/tool/audioLoopPointFinder/waveform-renderer.ts +53 -0
  36. package/src/tool/saveFileEditor/bibliography.astro +6 -0
  37. package/src/tool/saveFileEditor/bibliography.ts +12 -0
  38. package/src/tool/saveFileEditor/component.astro +351 -0
  39. package/src/tool/saveFileEditor/entry.ts +28 -0
  40. package/src/tool/saveFileEditor/game-save-file-editor.css +250 -0
  41. package/src/tool/saveFileEditor/i18n/de.ts +182 -0
  42. package/src/tool/saveFileEditor/i18n/en.ts +182 -0
  43. package/src/tool/saveFileEditor/i18n/es.ts +182 -0
  44. package/src/tool/saveFileEditor/i18n/fr.ts +182 -0
  45. package/src/tool/saveFileEditor/i18n/id.ts +182 -0
  46. package/src/tool/saveFileEditor/i18n/it.ts +182 -0
  47. package/src/tool/saveFileEditor/i18n/ja.ts +182 -0
  48. package/src/tool/saveFileEditor/i18n/ko.ts +182 -0
  49. package/src/tool/saveFileEditor/i18n/nl.ts +182 -0
  50. package/src/tool/saveFileEditor/i18n/pl.ts +182 -0
  51. package/src/tool/saveFileEditor/i18n/pt.ts +182 -0
  52. package/src/tool/saveFileEditor/i18n/ru.ts +182 -0
  53. package/src/tool/saveFileEditor/i18n/sv.ts +182 -0
  54. package/src/tool/saveFileEditor/i18n/tr.ts +182 -0
  55. package/src/tool/saveFileEditor/i18n/zh.ts +182 -0
  56. package/src/tool/saveFileEditor/index.ts +11 -0
  57. package/src/tool/saveFileEditor/logic.test.ts +69 -0
  58. package/src/tool/saveFileEditor/logic.ts +139 -0
  59. package/src/tool/saveFileEditor/seo.astro +15 -0
  60. package/src/tool/saveFileEditor/ui.ts +24 -0
  61. package/src/tools.ts +5 -0
@@ -0,0 +1,182 @@
1
+ import type { ToolLocaleContent } from '../../../types';
2
+ import type { SaveFileEditorUI } from '../ui';
3
+ import { bibliographyEntries } from '../bibliography';
4
+
5
+ export const content: ToolLocaleContent<SaveFileEditorUI> = {
6
+ slug: 'spelsparfils-editor',
7
+ title: 'Spelsparfils Obfuskator och Editor',
8
+ description: 'Avkoda, inspektera, redigera JSON data och kryptera om spelsparfiler med Base64, XOR maskering eller klartext 100% lokalt i din webbläsare.',
9
+ ui: {
10
+ title: 'Spelsparfils Obfuskator & Editor',
11
+ subtitle: 'Inspektera, ändra och kryptera lokala sparfiler säkert utan serverläckor',
12
+ dropSaveFile: 'Dra och släpp spelsparfilen här',
13
+ orSelectFile: 'eller klicka för att välja lokal fil',
14
+ encryptionMethod: 'Krypteringsformat',
15
+ methodBase64: 'Base64 Kodning',
16
+ methodXor: 'XOR Mask + Base64',
17
+ methodRaw: 'Klartext JSON / Okrypterad',
18
+ xorKeyLabel: 'XOR Hemlig Nyckel',
19
+ xorKeyPlaceholder: 't.ex. MinHemligaSpelnyckel2026',
20
+ jsonRawTitle: 'Avkodad JSON Data (Live Editor)',
21
+ encodeAndDownload: 'Kryptera och Ladda Ner Sparfil',
22
+ copyEncoded: 'Kopiera Krypterad Text',
23
+ copiedNotice: 'Kopierat till Urklipp!',
24
+ decodedKeysCount: 'Totalt Antal Parametrar',
25
+ dataSize: 'Datastorlek',
26
+ detectedFormat: 'Identifierat Format',
27
+ exportPreviewLabel: 'Förhandsgranskning av Krypterad Utdata',
28
+ decodePanelTitle: 'Avkodning och Live JSON Editor',
29
+ exportPanelTitle: 'Omkrypterad Utdata',
30
+ decodeError: 'Misslyckades med att avkoda sparfilen',
31
+ bytesUnit: 'B',
32
+ },
33
+ seo: [
34
+ {
35
+ type: 'title',
36
+ level: 2,
37
+ text: 'Säkerhets och Obfuskationsprotokoll för Spelsparfiler',
38
+ },
39
+ {
40
+ type: 'paragraph',
41
+ html: 'Datorspel serialiserar regelbundet spelarens framsteg, inventarieförråd, upplåsta nivåer och karaktärsegenskaper till permanenta lagringsformat mellan spelsessioner. För att förhindra obehöriga ändringar i vanliga textredigerare obfuskerar spelstudior sparfiler med binära kodningsscheman som Base64 eller bitvis XOR maskering mot en hemlig nyckel. Under interna kvalitetssäkringstester QA och felsökning behöver utvecklingsteam omedelbar tillgång till att inspektera råa JSON strukturer, testa gränsvärden och återkryptera ändrade data utan att behöva kompilera om hela spelet.',
42
+ },
43
+ {
44
+ type: 'stats',
45
+ columns: 4,
46
+ items: [
47
+ { label: 'Klientens Integritet', value: '100% Lokal' },
48
+ { label: 'Avkodare Som Stöds', value: 'Base64 / XOR / JSON' },
49
+ { label: 'Avkodningsfördröjning', value: '0 ms' },
50
+ { label: 'Dataintegritetsrisk', value: 'Noll' },
51
+ ],
52
+ },
53
+ {
54
+ type: 'title',
55
+ level: 2,
56
+ text: 'Jämförelse av Obfuskationsmetoder',
57
+ },
58
+ {
59
+ type: 'comparative',
60
+ columns: 3,
61
+ items: [
62
+ {
63
+ title: 'Base64 Kodning',
64
+ description: 'Snabb textkonvertering som förhindrar enkla ändringar i Anteckningar men saknar kryptografisk säkerhet.',
65
+ },
66
+ {
67
+ title: 'XOR Maskering + Base64',
68
+ description: 'Standardmetod inom oberoende spelutveckling. Blandar textbytes med en hemlig nyckel mot minnesredigerare.',
69
+ },
70
+ {
71
+ title: 'Klartext JSON',
72
+ description: 'Läsbar sparfil utan kryptering. Idealisk för tidiga prototypbyggen och interna felsökningar.',
73
+ },
74
+ ],
75
+ },
76
+ {
77
+ type: 'title',
78
+ level: 2,
79
+ text: 'QA Testmetoder för Verifiering av Sparfiler',
80
+ },
81
+ {
82
+ type: 'tip',
83
+ title: 'Bästa Praxis för Säkerhet i Sparfiler under QA',
84
+ html: 'Använd alltid separata felsökningsnycklar för interna testbyggen. Använd lokala inspektörer för att verifiera gränsvärden utan att kompilera om spelkoden.',
85
+ },
86
+ {
87
+ type: 'title',
88
+ level: 2,
89
+ text: 'Vägledningstabell för Spelparametrar',
90
+ },
91
+ {
92
+ type: 'table',
93
+ headers: ['Datatyp', 'Rekommenderat Format', 'Vanligt Användningsområde', 'Obfuskationslager'],
94
+ rows: [
95
+ ['Numeriska Heltal', '32-bitars Heltal', 'Mynt, Nivå, XP, Ammunition', 'XOR-maskerad'],
96
+ ['Boolska Flaggor', 'Standard Boolean', 'Tutorial Slutförd, Boss Besegrad', 'Base64 / XOR'],
97
+ ['Nästlade Objekt', 'JSON Hierarki', 'Spelarinventarium, Färdighetsträd', 'Base64-kodad'],
98
+ ['Tidsstämplar', 'ISO 8601 UTC', 'Daglig Inloggning, Spartidsstämpel', 'XOR-maskerad'],
99
+ ],
100
+ },
101
+ {
102
+ type: 'title',
103
+ level: 2,
104
+ text: 'Reverse Engineering och Skydd Mot Manipulation',
105
+ },
106
+ {
107
+ type: 'paragraph',
108
+ html: 'Även om obfuskering på klientsidan förhindrar vanliga spelare från att ändra sparfiler, är XOR och Base64 inte fullständiga kryptografiska algoritmer. Verktyg för minnesanalys som RenderDoc eller x64dbg kan utläsa nyckelgenerering direkt från kompilerade filer. För tävlingsinriktade flerspelarspel krävs validering på serversidan eller kryptografiska HMAC signaturer.',
109
+ },
110
+ ],
111
+ faqTitle: 'Vanliga Frågor',
112
+ faq: [
113
+ {
114
+ question: 'Laddas mina sparfiler upp till en extern server?',
115
+ answer: 'Nej. All avkodning, JSON redigering och återkryptering sker till 100% lokalt i din webbläsare.',
116
+ },
117
+ {
118
+ question: 'Hur fungerar XOR maskering i spelmotorer som Unity eller Godot?',
119
+ answer: 'XOR maskering utför bitvisa XOR operationer på UTF-8 bytes i JSON strängen med tecknen från en hemlig nyckel.',
120
+ },
121
+ ],
122
+ howTo: [
123
+ {
124
+ name: 'Ladda eller Klistra In Sparfil',
125
+ text: 'Ladda upp din krypterade sparfil eller dra den till uppladdningsytan.',
126
+ },
127
+ {
128
+ name: 'Välj Avkodningsmetod och Nyckel',
129
+ text: 'Välj Base64 eller XOR Maskering och ange nyckeln.',
130
+ },
131
+ {
132
+ name: 'Redigera JSON Data',
133
+ text: 'Ändra nivåer, guld, föremål och spelinställningar direkt i live editorn.',
134
+ },
135
+ {
136
+ name: 'Kryptera och Exportera',
137
+ text: 'Ladda ner den modifierade sparfilen redo för testning.',
138
+ },
139
+ ],
140
+ schemas: [
141
+ {
142
+ '@context': 'https://schema.org',
143
+ '@type': 'SoftwareApplication',
144
+ name: 'Spelsparfils Editor',
145
+ applicationCategory: 'DeveloperApplication',
146
+ operatingSystem: 'Any',
147
+ offers: {
148
+ '@type': 'Offer',
149
+ price: '0',
150
+ priceCurrency: 'SEK',
151
+ },
152
+ },
153
+ {
154
+ '@context': 'https://schema.org',
155
+ '@type': 'FAQPage',
156
+ mainEntity: [
157
+ {
158
+ '@type': 'Question',
159
+ name: 'Laddas mina sparfiler upp till en extern server?',
160
+ acceptedAnswer: {
161
+ '@type': 'Answer',
162
+ text: 'Nej. All behandling sker 100% lokalt i webbläsaren.',
163
+ },
164
+ },
165
+ ],
166
+ },
167
+ {
168
+ '@context': 'https://schema.org',
169
+ '@type': 'HowTo',
170
+ name: 'Hur man Redigerar Krypterade Spelsparfiler',
171
+ step: [
172
+ {
173
+ '@type': 'HowToStep',
174
+ name: 'Ladda Sparfil',
175
+ text: 'Ladda upp din krypterade sparfil.',
176
+ },
177
+ ],
178
+ },
179
+ ],
180
+ bibliographyTitle: 'Referenser och Vidare Läsning',
181
+ bibliography: bibliographyEntries,
182
+ };
@@ -0,0 +1,182 @@
1
+ import type { ToolLocaleContent } from '../../../types';
2
+ import type { SaveFileEditorUI } from '../ui';
3
+ import { bibliographyEntries } from '../bibliography';
4
+
5
+ export const content: ToolLocaleContent<SaveFileEditorUI> = {
6
+ slug: 'oyun-kayit-dosyasi-duzenleyici',
7
+ title: 'Oyun Kayıt Dosyası Karartıcı ve Düzenleyici',
8
+ description: 'Base64, XOR maskeleme veya düz metin kullanarak oyun kayıt dosyalarını tarayıcınızda %100 yerel olarak çözün, inceleyin, JSON verilerini düzenleyin ve yeniden şifreleyin.',
9
+ ui: {
10
+ title: 'Oyun Kayıt Dosyası Karartıcı & Düzenleyici',
11
+ subtitle: 'Sunucuya veri göndermeden yerel kayıt dosyalarını güvenle inceleyin, değiştirin ve şifreleyin',
12
+ dropSaveFile: 'Oyun kayıt dosyasını buraya sürükleyip bırakın',
13
+ orSelectFile: 'veya yerel dosya seçmek için tıklayın',
14
+ encryptionMethod: 'Şifreleme Biçimi',
15
+ methodBase64: 'Base64 Kodlama',
16
+ methodXor: 'XOR Maskesi + Base64',
17
+ methodRaw: 'Düz JSON / Şifresiz',
18
+ xorKeyLabel: 'Gizli XOR Anahtarı',
19
+ xorKeyPlaceholder: 'ör. GizliOyunAnahtarim2026',
20
+ jsonRawTitle: 'Çözülmüş JSON Verisi (Canlı Düzenleyici)',
21
+ encodeAndDownload: 'Şifrele ve Dosyayı İndir',
22
+ copyEncoded: 'Şifrelenmiş Metni Kopyala',
23
+ copiedNotice: 'Panoya Kopyalandı!',
24
+ decodedKeysCount: 'Toplam Parametre',
25
+ dataSize: 'Veri Boyutu',
26
+ detectedFormat: 'Algılanan Biçim',
27
+ exportPreviewLabel: 'Şifrelenmiş Çıktı Önizlemesi',
28
+ decodePanelTitle: 'Çözümleme ve Canlı JSON Düzenleyici',
29
+ exportPanelTitle: 'Yeniden Şifrelenmiş Çıktı Verisi',
30
+ decodeError: 'Kayıt dosyasının şifresi çözülemedi',
31
+ bytesUnit: 'B',
32
+ },
33
+ seo: [
34
+ {
35
+ type: 'title',
36
+ level: 2,
37
+ text: 'Oyun Kayıt Dosyası Güvenliği ve Karartma Protokolleri',
38
+ },
39
+ {
40
+ type: 'paragraph',
41
+ html: 'Oyunlar, oyuncunun ilerleme durumunu, envanter sayısını, açılan seviyeleri ve karakter özelliklerini oturumlar arasında korumak için kalıcı depolama biçimlerine dönüştürür. Son kullanıcıların düz metin düzenleyicileriyle izinsiz değişiklik yapmasını önlemek için oyun stüdyoları, kayıt dosyalarını Base64 veya gizli bir anahtar kullanarak bit düzeyinde XOR maskeleme ile karartır. İç Kalite Kontrol QA testleri ve canlı operasyon hatası giderme sırasında geliştirme ekipleri, JSON yapılarını incelemek, sınır durumlarını test etmek ve oyun dosyalarını yeniden derlemeden değiştirilmiş verileri şifrelemek için anlık araçlara ihtiyaç duyar.',
42
+ },
43
+ {
44
+ type: 'stats',
45
+ columns: 4,
46
+ items: [
47
+ { label: 'İstemci İşleme Gizliliği', value: '%100 Yerel' },
48
+ { label: 'Desteklenen Çözücüler', value: 'Base64 / XOR / JSON' },
49
+ { label: 'Çözümleme Gecikmesi', value: '0 ms' },
50
+ { label: 'Veri Sızıntısı Riski', value: 'Sıfır' },
51
+ ],
52
+ },
53
+ {
54
+ type: 'title',
55
+ level: 2,
56
+ text: 'Karartma Yöntemlerinin Karşılaştırılması',
57
+ },
58
+ {
59
+ type: 'comparative',
60
+ columns: 3,
61
+ items: [
62
+ {
63
+ title: 'Base64 Kodlama',
64
+ description: 'Not defterinde basit düzenlemeleri engelleyen hızlı metin dönüştürme yöntemi ancak kriptografik güvenlik sağlamaz.',
65
+ },
66
+ {
67
+ title: 'XOR Maskeleme + Base64',
68
+ description: 'Bağımsız oyun geliştirmede standart uygulama. Bellek düzenleyicilerine karşı metin baytlarını gizli bir anahtarla harmanlar.',
69
+ },
70
+ {
71
+ title: 'Düz JSON Verisi',
72
+ description: 'Şifrelenmemiş okunabilir kayıt durumu. İlk prototip oluşturma ve dahili hata ayıklama için idealdir.',
73
+ },
74
+ ],
75
+ },
76
+ {
77
+ type: 'title',
78
+ level: 2,
79
+ text: 'Kayıt Durumu Doğrulaması İçin QA Test Uygulamaları',
80
+ },
81
+ {
82
+ type: 'tip',
83
+ title: 'QA Sırasında Kayıt Dosyası Güvenliği İçin En İyi Uygulamalar',
84
+ html: 'Dahili sürümler ve üretim sürümleri için her zaman ayrı hata ayıklama anahtarları kullanın. Sınır hatalarını doğrularken oyun kodunu yeniden derlemeden yerel düzenleyicileri kullanın.',
85
+ },
86
+ {
87
+ type: 'title',
88
+ level: 2,
89
+ text: 'Oyun Durumu Parametre Yönergeleri Tablosu',
90
+ },
91
+ {
92
+ type: 'table',
93
+ headers: ['Veri Türü', 'Önerilen Biçim', 'Yaygın Kullanım Alanı', 'Karartma Katmanı'],
94
+ rows: [
95
+ ['Sayısal Tamsayılar', '32-bit Tamsayı', 'Altın, Seviye, XP, Cephane', 'XOR Maskeli'],
96
+ ['Mantıksal Bayraklar', 'Standart Boolean', 'Eğitim Tamamlandı, Patron Yenildi', 'Base64 / XOR'],
97
+ ['İç İçe Nesneler', 'JSON Hiyerarşisi', 'Oyuncu Envanteri, Yetenek Ağacı', 'Base64 Kodlu'],
98
+ ['Zaman Damgası Metni', 'ISO 8601 UTC', 'Günlük Giriş, Kayıt Zamanı', 'XOR Maskeli'],
99
+ ],
100
+ },
101
+ {
102
+ type: 'title',
103
+ level: 2,
104
+ text: 'Tersine Mühendislik ve Kurcalamaya Karşı Koruma',
105
+ },
106
+ {
107
+ type: 'paragraph',
108
+ html: 'İstemci tarafındaki karartma sıradan oyuncuların kayıt dosyalarını değiştirmesini engellese de XOR ve Base64 gerçek kriptografik algoritmalar değildir. RenderDoc veya x64dbg gibi bellek analiz araçları derlenmiş dosyalardan anahtar oluşturma kodlarını inceleyebilir. Rekabetçi çok oyunculu oyunlar için sunucu tarafı doğrulaması veya HMAC imzaları gereklidir.',
109
+ },
110
+ ],
111
+ faqTitle: 'Sıkça Sorulan Sorular',
112
+ faq: [
113
+ {
114
+ question: 'Oyun kayıt dosyalarım uzak bir sunucuya yükleniyor mu?',
115
+ answer: 'Hayır. Tüm çözümleme, JSON düzenleme ve yeniden şifreleme işlemleri %100 web tarayıcınızın içinde yerel olarak gerçekleşir.',
116
+ },
117
+ {
118
+ question: 'Unity veya Godot gibi motorlarda XOR karartması nasıl çalışır?',
119
+ answer: 'XOR karartması, JSON metninin UTF-8 baytları üzerinde gizli bir anahtarın karakterleriyle bit düzeyinde XOR işlemi uygular.',
120
+ },
121
+ ],
122
+ howTo: [
123
+ {
124
+ name: 'Kayıt Dosyasını Yükleyin veya Yapıştırın',
125
+ text: 'Şifrelenmiş kayıt dosyanızı yükleyin veya sürükleyip bırakın.',
126
+ },
127
+ {
128
+ name: 'Çözümleme Yöntemini ve Anahtarı Seçin',
129
+ text: 'Base64 veya XOR Maskelemeyi seçin ve gizli anahtarı girin.',
130
+ },
131
+ {
132
+ name: 'JSON Durumunu Düzenleyin',
133
+ text: 'Canlı düzenleyicide seviye, altın, eşya ve oyun bayraklarını değiştirin.',
134
+ },
135
+ {
136
+ name: 'Şifreleyin ve Dışa Aktarın',
137
+ text: 'Test için hazır olan yeni şifrelenmiş kayıt dosyasını indirin.',
138
+ },
139
+ ],
140
+ schemas: [
141
+ {
142
+ '@context': 'https://schema.org',
143
+ '@type': 'SoftwareApplication',
144
+ name: 'Oyun Kayıt Dosyası Düzenleyici',
145
+ applicationCategory: 'DeveloperApplication',
146
+ operatingSystem: 'Any',
147
+ offers: {
148
+ '@type': 'Offer',
149
+ price: '0',
150
+ priceCurrency: 'TRY',
151
+ },
152
+ },
153
+ {
154
+ '@context': 'https://schema.org',
155
+ '@type': 'FAQPage',
156
+ mainEntity: [
157
+ {
158
+ '@type': 'Question',
159
+ name: 'Oyun kayıt dosyalarım uzak bir sunucuya yükleniyor mu?',
160
+ acceptedAnswer: {
161
+ '@type': 'Answer',
162
+ text: 'Hayır. Tüm işlemler %100 tarayıcınızda gerçekleşir.',
163
+ },
164
+ },
165
+ ],
166
+ },
167
+ {
168
+ '@context': 'https://schema.org',
169
+ '@type': 'HowTo',
170
+ name: 'Şifreli Oyun Kayıt Dosyaları Nasıl Düzenlenir',
171
+ step: [
172
+ {
173
+ '@type': 'HowToStep',
174
+ name: 'Dosyayı Yükleyin',
175
+ text: 'Şifrelenmiş kayıt dosyanızı yükleyin.',
176
+ },
177
+ ],
178
+ },
179
+ ],
180
+ bibliographyTitle: 'Kaynaklar ve Ek Okumalar',
181
+ bibliography: bibliographyEntries,
182
+ };
@@ -0,0 +1,182 @@
1
+ import type { ToolLocaleContent } from '../../../types';
2
+ import type { SaveFileEditorUI } from '../ui';
3
+ import { bibliographyEntries } from '../bibliography';
4
+
5
+ export const content: ToolLocaleContent<SaveFileEditorUI> = {
6
+ slug: 'game-save-file-editor',
7
+ title: '游戏存档文件混淆与在线编辑器',
8
+ description: '在浏览器本地100%安全地解密、检查、编辑JSON结构并使用Base64、XOR掩码或明文重新加密游戏存档文件。',
9
+ ui: {
10
+ title: '游戏存档文件混淆与在线编辑器',
11
+ subtitle: '无需上传服务器,安全地检查、修改和加密本地游戏存档状态文件',
12
+ dropSaveFile: '将游戏存档文件拖放到此处',
13
+ orSelectFile: '或点击浏览本地文件',
14
+ encryptionMethod: '加密格式',
15
+ methodBase64: 'Base64 编码',
16
+ methodXor: 'XOR 掩码 + Base64',
17
+ methodRaw: '明文 JSON / 未加密',
18
+ xorKeyLabel: 'XOR 密钥',
19
+ xorKeyPlaceholder: '例如 MySecretGameKey2026',
20
+ jsonRawTitle: '已解密的 JSON 数据(实时编辑器)',
21
+ encodeAndDownload: '加密并下载存档文件',
22
+ copyEncoded: '复制加密文本',
23
+ copiedNotice: '已复制到剪贴板!',
24
+ decodedKeysCount: '参数总数',
25
+ dataSize: '数据大小',
26
+ detectedFormat: '检测到的格式',
27
+ exportPreviewLabel: '加密输出预览',
28
+ decodePanelTitle: '解密与实时 JSON 编辑器',
29
+ exportPanelTitle: '重新加密输出数据',
30
+ decodeError: '无法解密游戏存档文件',
31
+ bytesUnit: '字节',
32
+ },
33
+ seo: [
34
+ {
35
+ type: 'title',
36
+ level: 2,
37
+ text: '游戏存档文件安全与混淆协议',
38
+ },
39
+ {
40
+ type: 'paragraph',
41
+ html: '在电子游戏开发中,玩家的进度、道具数量、解锁关卡和角色属性等状态数据通常会被序列化并持久化存储。为了防止普通玩家通过文本编辑器随意篡改存档,游戏开发团队通常会使用 Base64 编码或基于自定义密钥的按位 XOR 掩码对存档文件进行混淆。在内部 QA 测试和在线运营调试过程中,开发人员需要能够实时查看原始 JSON 结构、设定边界测试状态,并在无需重新编译游戏二进制文件的情况下重新加密导出存档。',
42
+ },
43
+ {
44
+ type: 'stats',
45
+ columns: 4,
46
+ items: [
47
+ { label: '客户端处理隐私', value: '100% 本地' },
48
+ { label: '支持的解密方式', value: 'Base64 / XOR / JSON' },
49
+ { label: '解密延迟', value: '0 毫秒' },
50
+ { label: '数据泄漏风险', value: '零' },
51
+ ],
52
+ },
53
+ {
54
+ type: 'title',
55
+ level: 2,
56
+ text: '混淆方案对比',
57
+ },
58
+ {
59
+ type: 'comparative',
60
+ columns: 3,
61
+ items: [
62
+ {
63
+ title: 'Base64 编码',
64
+ description: '轻量级的文本转换格式,可防止在记事本中直接修改,但不具备真正的密码学安全性。',
65
+ },
66
+ {
67
+ title: 'XOR 掩码 + Base64',
68
+ description: '独立游戏开发中的标准做法。将文本字节与密钥混合,有效防御内存修改器和简易作弊工具。',
69
+ },
70
+ {
71
+ title: '明文 JSON 数据',
72
+ description: '未加密的可读存档状态。非常适合早期原型设计和内部团队快速迭代。',
73
+ },
74
+ ],
75
+ },
76
+ {
77
+ type: 'title',
78
+ level: 2,
79
+ text: '存档状态验证的 QA 测试实践',
80
+ },
81
+ {
82
+ type: 'tip',
83
+ title: 'QA 测试中的存档安全最佳实践',
84
+ html: '请务必为内部测试构建与生产构建配置不同的调试密钥。验证边界条件 Bug 时,可使用本地树状编辑器强行设置道具上限和测试数值,无需重新编译代码。',
85
+ },
86
+ {
87
+ type: 'title',
88
+ level: 2,
89
+ text: '游戏状态参数指南表',
90
+ },
91
+ {
92
+ type: 'table',
93
+ headers: ['数据类型', '推荐格式', '常见应用场景', '混淆层'],
94
+ rows: [
95
+ ['数值整数', '32 位整数', '金币、等级、经验值、弹药', 'XOR 掩码'],
96
+ ['布尔标志', '标准布尔值', '新手教程完成、Boss 击败', 'Base64 / XOR'],
97
+ ['嵌套对象', 'JSON 层次结构', '玩家背包、技能树', 'Base64 编码'],
98
+ ['时间戳字符串', 'ISO 8601 UTC', '每日签到、存档时间戳', 'XOR 掩码'],
99
+ ],
100
+ },
101
+ {
102
+ type: 'title',
103
+ level: 2,
104
+ text: '逆向工程与防篡改考量',
105
+ },
106
+ {
107
+ type: 'paragraph',
108
+ html: '尽管客户端混淆可以防止普通玩家篡改存档,但 XOR 掩码和 Base64 编码并非强加密算法。使用 RenderDoc 或 x64dbg 等内存调试工具可以从编译好的二进制文件中分析出密钥生成逻辑。对于竞技类多人游戏,必须结合服务器端权威验证或 HMAC 数字签名来防止篡改。',
109
+ },
110
+ ],
111
+ faqTitle: '常见问题解答',
112
+ faq: [
113
+ {
114
+ question: '我的游戏存档文件会被上传到远程服务器吗?',
115
+ answer: '不会。所有解密、JSON 编辑和重新加密过程 100% 在您的 Web 浏览器 JavaScript 引擎内部本地完成。',
116
+ },
117
+ {
118
+ question: 'XOR 密钥混淆在 Unity 或 Godot 等游戏引擎中是如何工作的?',
119
+ answer: 'XOR 混淆会遍历序列化 JSON 字符串的 UTF-8 字节,将其与密钥字符逐字节进行按位 XOR 异或运算,再将结果转换为 Base64 编码。',
120
+ },
121
+ ],
122
+ howTo: [
123
+ {
124
+ name: '加载或粘贴存档文件',
125
+ text: '上传加密的游戏存档文件或将文件拖入加载区域。',
126
+ },
127
+ {
128
+ name: '选择解密方法和密钥',
129
+ text: '选择 Base64 或 XOR 掩码,并输入对应的游戏秘钥。',
130
+ },
131
+ {
132
+ name: '编辑 JSON 状态',
133
+ text: '在实时编辑器中调整等级、金币、道具或游戏状态标志。',
134
+ },
135
+ {
136
+ name: '加密并导出',
137
+ text: '选择目标输出格式并下载修改后的存档文件以供游戏测试。',
138
+ },
139
+ ],
140
+ schemas: [
141
+ {
142
+ '@context': 'https://schema.org',
143
+ '@type': 'SoftwareApplication',
144
+ name: '游戏存档文件编辑器',
145
+ applicationCategory: 'DeveloperApplication',
146
+ operatingSystem: 'Any',
147
+ offers: {
148
+ '@type': 'Offer',
149
+ price: '0',
150
+ priceCurrency: 'CNY',
151
+ },
152
+ },
153
+ {
154
+ '@context': 'https://schema.org',
155
+ '@type': 'FAQPage',
156
+ mainEntity: [
157
+ {
158
+ '@type': 'Question',
159
+ name: '我的游戏存档文件会被上传到远程服务器吗?',
160
+ acceptedAnswer: {
161
+ '@type': 'Answer',
162
+ text: '不会。所有处理过程 100% 在您的浏览器内部完成。',
163
+ },
164
+ },
165
+ ],
166
+ },
167
+ {
168
+ '@context': 'https://schema.org',
169
+ '@type': 'HowTo',
170
+ name: '如何编辑加密的游戏存档文件',
171
+ step: [
172
+ {
173
+ '@type': 'HowToStep',
174
+ name: '加载存档文件',
175
+ text: '上传加密的游戏存档文件。',
176
+ },
177
+ ],
178
+ },
179
+ ],
180
+ bibliographyTitle: '参考资料与延伸阅读',
181
+ bibliography: bibliographyEntries,
182
+ };
@@ -0,0 +1,11 @@
1
+ import type { ToolDefinition } from '../../types';
2
+ import { saveFileEditor } from './entry';
3
+
4
+ export * from './entry';
5
+
6
+ export const SAVE_FILE_EDITOR_TOOL: ToolDefinition = {
7
+ entry: saveFileEditor,
8
+ Component: () => import('./component.astro'),
9
+ SEOComponent: () => import('./seo.astro'),
10
+ BibliographyComponent: () => import('./bibliography.astro'),
11
+ };
@@ -0,0 +1,69 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import {
3
+ decodeSaveData,
4
+ encodeSaveData,
5
+ applyXor,
6
+ bytesToBase64,
7
+ base64ToBytes,
8
+ strToUtf8Bytes,
9
+ utf8BytesToStr,
10
+ detectFormat,
11
+ } from './logic';
12
+
13
+ describe('saveFileEditor logic', () => {
14
+ const sampleObj = { level: 10, coins: 500, player: 'Hero' };
15
+ const sampleJson = JSON.stringify(sampleObj, null, 2);
16
+
17
+ it('converts utf8 bytes back and forth', () => {
18
+ const bytes = strToUtf8Bytes('Hello World!');
19
+ expect(utf8BytesToStr(bytes)).toBe('Hello World!');
20
+ });
21
+
22
+ it('converts base64 back and forth', () => {
23
+ const bytes = strToUtf8Bytes(sampleJson);
24
+ const b64 = bytesToBase64(bytes);
25
+ const resultBytes = base64ToBytes(b64);
26
+ expect(utf8BytesToStr(resultBytes)).toBe(sampleJson);
27
+ });
28
+
29
+ it('applies XOR correctly', () => {
30
+ const key = 'secret123';
31
+ const bytes = strToUtf8Bytes('GameSaveData');
32
+ const obfuscated = applyXor(bytes, key);
33
+ const restored = applyXor(obfuscated, key);
34
+ expect(utf8BytesToStr(restored)).toBe('GameSaveData');
35
+ });
36
+
37
+ it('decodes raw JSON save data', () => {
38
+ const res = decodeSaveData(sampleJson, { method: 'raw', xorKey: '' });
39
+ expect(res.success).toBe(true);
40
+ expect(res.data).toEqual(sampleObj);
41
+ });
42
+
43
+ it('encodes and decodes Base64 save data', () => {
44
+ const b64 = encodeSaveData(sampleObj, { method: 'base64', xorKey: '' });
45
+ const decoded = decodeSaveData(b64, { method: 'base64', xorKey: '' });
46
+ expect(decoded.success).toBe(true);
47
+ expect(decoded.data).toEqual(sampleObj);
48
+ });
49
+
50
+ it('encodes and decodes XOR + Base64 save data', () => {
51
+ const key = 'my_game_key';
52
+ const encoded = encodeSaveData(sampleObj, { method: 'xor', xorKey: key });
53
+ const decoded = decodeSaveData(encoded, { method: 'xor', xorKey: key });
54
+ expect(decoded.success).toBe(true);
55
+ expect(decoded.data).toEqual(sampleObj);
56
+ });
57
+
58
+ it('auto-detects format', () => {
59
+ const rawFormat = detectFormat(sampleJson);
60
+ expect(rawFormat).toBe('raw');
61
+
62
+ const b64Str = encodeSaveData(sampleObj, { method: 'base64', xorKey: '' });
63
+ expect(detectFormat(b64Str)).toBe('base64');
64
+
65
+ const key = 'my_game_key';
66
+ const xorStr = encodeSaveData(sampleObj, { method: 'xor', xorKey: key });
67
+ expect(detectFormat(xorStr, key)).toBe('xor');
68
+ });
69
+ });