silkedit 0.1.10

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 (283) hide show
  1. checksums.yaml +7 -0
  2. data/.rbcli +0 -0
  3. data/CHANGELOG.md +7 -0
  4. data/CODE_OF_CONDUCT.md +132 -0
  5. data/LICENSE.txt +169 -0
  6. data/README.md +302 -0
  7. data/Rakefile +8 -0
  8. data/exe/silkedit +13 -0
  9. data/lib/commands/backup_restore.rb +25 -0
  10. data/lib/commands/cheat.rb +74 -0
  11. data/lib/commands/edit_diff.rb +47 -0
  12. data/lib/commands/examples/command.rb +51 -0
  13. data/lib/commands/examples/script.rb +36 -0
  14. data/lib/commands/journal.rb +34 -0
  15. data/lib/commands/permasave_permaload.rb +62 -0
  16. data/lib/commands/scripts/.keep +0 -0
  17. data/lib/commands/unpack_repack.rb +27 -0
  18. data/lib/commands/zone_mkzone.rb +103 -0
  19. data/lib/config/config.rb +28 -0
  20. data/lib/config/envvars.rb +23 -0
  21. data/lib/config/hooks.rb +22 -0
  22. data/lib/config/logger.rb +36 -0
  23. data/lib/config/parser.rb +34 -0
  24. data/lib/config/updatechecker.rb +12 -0
  25. data/lib/silkedit/cheats/cheatengine.rb +33 -0
  26. data/lib/silkedit/cheats/hollow_knight_cheats.rb +5 -0
  27. data/lib/silkedit/cheats/merger.rb +107 -0
  28. data/lib/silkedit/cheats/silksong_cheats.rb +161 -0
  29. data/lib/silkedit/cheats/silksong_enemyjournal.rb +120 -0
  30. data/lib/silkedit/cheats/silksong_zoner.rb +98 -0
  31. data/lib/silkedit/config/savegame.yaml +13 -0
  32. data/lib/silkedit/config/silkedit.yaml +6 -0
  33. data/lib/silkedit/config/silksong/cheatdata.yaml +1341 -0
  34. data/lib/silkedit/config/silksong/enemylist.yaml +1424 -0
  35. data/lib/silkedit/config/silksong/old.yaml +4345 -0
  36. data/lib/silkedit/config/silksong/permasaves.yaml +12 -0
  37. data/lib/silkedit/config/silksong/unfinished.yaml +628 -0
  38. data/lib/silkedit/config/silksong/zones.yaml +1738 -0
  39. data/lib/silkedit/images/.keep +0 -0
  40. data/lib/silkedit/images/silksong/Aknid.png +0 -0
  41. data/lib/silkedit/images/silksong/Alita.png +0 -0
  42. data/lib/silkedit/images/silksong/Barnak.png +0 -0
  43. data/lib/silkedit/images/silksong/Beastfly.png +0 -0
  44. data/lib/silkedit/images/silksong/Bell_Beast.png +0 -0
  45. data/lib/silkedit/images/silksong/Bell_Eater.png +0 -0
  46. data/lib/silkedit/images/silksong/Bloatroach.png +0 -0
  47. data/lib/silkedit/images/silksong/Broodmother.png +0 -0
  48. data/lib/silkedit/images/silksong/Brushflit.png +0 -0
  49. data/lib/silkedit/images/silksong/Burning_Bug.png +0 -0
  50. data/lib/silkedit/images/silksong/Caranid.png +0 -0
  51. data/lib/silkedit/images/silksong/Choir_Bellbearer.png +0 -0
  52. data/lib/silkedit/images/silksong/Choir_Clapper.png +0 -0
  53. data/lib/silkedit/images/silksong/Choir_Elder.png +0 -0
  54. data/lib/silkedit/images/silksong/Choir_Flyer.png +0 -0
  55. data/lib/silkedit/images/silksong/Choir_Hornhead.png +0 -0
  56. data/lib/silkedit/images/silksong/Choir_Pouncer.png +0 -0
  57. data/lib/silkedit/images/silksong/Choristor.png +0 -0
  58. data/lib/silkedit/images/silksong/Clawmaiden.png +0 -0
  59. data/lib/silkedit/images/silksong/Clover_Dancers.png +0 -0
  60. data/lib/silkedit/images/silksong/Cloverstag.png +0 -0
  61. data/lib/silkedit/images/silksong/Cogwork_Choirbug.png +0 -0
  62. data/lib/silkedit/images/silksong/Cogwork_Clapper.png +0 -0
  63. data/lib/silkedit/images/silksong/Cogwork_Cleanser.png +0 -0
  64. data/lib/silkedit/images/silksong/Cogwork_Crawler.png +0 -0
  65. data/lib/silkedit/images/silksong/Cogwork_Dancers.png +0 -0
  66. data/lib/silkedit/images/silksong/Cogwork_Defender.png +0 -0
  67. data/lib/silkedit/images/silksong/Cogwork_Hauler.png +0 -0
  68. data/lib/silkedit/images/silksong/Cogwork_Spine.png +0 -0
  69. data/lib/silkedit/images/silksong/Cogwork_Underfly.png +0 -0
  70. data/lib/silkedit/images/silksong/Cogworker.png +0 -0
  71. data/lib/silkedit/images/silksong/Conchfly.png +0 -0
  72. data/lib/silkedit/images/silksong/Coral_Furm.png +0 -0
  73. data/lib/silkedit/images/silksong/Corrcrust_Karaka.png +0 -0
  74. data/lib/silkedit/images/silksong/Covetous_Pilgrim.png +0 -0
  75. data/lib/silkedit/images/silksong/Craggler.png +0 -0
  76. data/lib/silkedit/images/silksong/Cragglite.png +0 -0
  77. data/lib/silkedit/images/silksong/Craw.png +0 -0
  78. data/lib/silkedit/images/silksong/Craw_Juror.png +0 -0
  79. data/lib/silkedit/images/silksong/Crawfather.png +0 -0
  80. data/lib/silkedit/images/silksong/Crust_King_Khann.png +0 -0
  81. data/lib/silkedit/images/silksong/Crustcrag.png +0 -0
  82. data/lib/silkedit/images/silksong/Crustcrawler.png +0 -0
  83. data/lib/silkedit/images/silksong/Deep_Diver.png +0 -0
  84. data/lib/silkedit/images/silksong/Disgraced_Chef_Lugoli.png +0 -0
  85. data/lib/silkedit/images/silksong/Drapefly.png +0 -0
  86. data/lib/silkedit/images/silksong/Drapelord.png +0 -0
  87. data/lib/silkedit/images/silksong/Drapemite.png +0 -0
  88. data/lib/silkedit/images/silksong/Dreg_Catcher.png +0 -0
  89. data/lib/silkedit/images/silksong/Dreg_Husk.png +0 -0
  90. data/lib/silkedit/images/silksong/Dregwheel.png +0 -0
  91. data/lib/silkedit/images/silksong/Driftlin.png +0 -0
  92. data/lib/silkedit/images/silksong/Driznarga.png +0 -0
  93. data/lib/silkedit/images/silksong/Driznit.png +0 -0
  94. data/lib/silkedit/images/silksong/Ductsucker.png +0 -0
  95. data/lib/silkedit/images/silksong/Elder_Pilgrim.png +0 -0
  96. data/lib/silkedit/images/silksong/Envoy.png +0 -0
  97. data/lib/silkedit/images/silksong/Escalion.png +0 -0
  98. data/lib/silkedit/images/silksong/Father_of_the_Flame.png +0 -0
  99. data/lib/silkedit/images/silksong/Fertid.png +0 -0
  100. data/lib/silkedit/images/silksong/First_Sinner.png +0 -0
  101. data/lib/silkedit/images/silksong/Flapping_Fertid.png +0 -0
  102. data/lib/silkedit/images/silksong/Flintbeetle.png +0 -0
  103. data/lib/silkedit/images/silksong/Flintflame_Flyer.png +0 -0
  104. data/lib/silkedit/images/silksong/Flintstone_Flyer.png +0 -0
  105. data/lib/silkedit/images/silksong/Fluttermite.png +0 -0
  106. data/lib/silkedit/images/silksong/Forebrothers_Signis_&_Gron.png +0 -0
  107. data/lib/silkedit/images/silksong/Fourth_Chorus.png +0 -0
  108. data/lib/silkedit/images/silksong/Freshfly.png +0 -0
  109. data/lib/silkedit/images/silksong/Furm.png +0 -0
  110. data/lib/silkedit/images/silksong/Gahlia.png +0 -0
  111. data/lib/silkedit/images/silksong/Gargant_Gloom.png +0 -0
  112. data/lib/silkedit/images/silksong/Garpid.png +0 -0
  113. data/lib/silkedit/images/silksong/Giant_Drapemite.png +0 -0
  114. data/lib/silkedit/images/silksong/Gloomsac.png +0 -0
  115. data/lib/silkedit/images/silksong/Grand_Mother_Silk.png +0 -0
  116. data/lib/silkedit/images/silksong/Grand_Reed.png +0 -0
  117. data/lib/silkedit/images/silksong/Great_Conchfly.png +0 -0
  118. data/lib/silkedit/images/silksong/Groal_the_Great.png +0 -0
  119. data/lib/silkedit/images/silksong/Grom.png +0 -0
  120. data/lib/silkedit/images/silksong/Gromling.png +0 -0
  121. data/lib/silkedit/images/silksong/Guardfly.png +0 -0
  122. data/lib/silkedit/images/silksong/Gurr_the_Outcast.png +0 -0
  123. data/lib/silkedit/images/silksong/Hardbone_Elder.png +0 -0
  124. data/lib/silkedit/images/silksong/Hardbone_Hopper.png +0 -0
  125. data/lib/silkedit/images/silksong/Hoker.png +0 -0
  126. data/lib/silkedit/images/silksong/Huge_Flea.png +0 -0
  127. data/lib/silkedit/images/silksong/Imoba.png +0 -0
  128. data/lib/silkedit/images/silksong/Judge.png +0 -0
  129. data/lib/silkedit/images/silksong/Kai.png +0 -0
  130. data/lib/silkedit/images/silksong/Kakri.png +0 -0
  131. data/lib/silkedit/images/silksong/Karak_Gor.png +0 -0
  132. data/lib/silkedit/images/silksong/Karaka.png +0 -0
  133. data/lib/silkedit/images/silksong/Kilik.png +0 -0
  134. data/lib/silkedit/images/silksong/Kindanir.png +0 -0
  135. data/lib/silkedit/images/silksong/Lace.png +0 -0
  136. data/lib/silkedit/images/silksong/Lampbearer.png +0 -0
  137. data/lib/silkedit/images/silksong/Last_Claw.png +0 -0
  138. data/lib/silkedit/images/silksong/Last_Judge.png +0 -0
  139. data/lib/silkedit/images/silksong/Lavalarga.png +0 -0
  140. data/lib/silkedit/images/silksong/Lavalug.png +0 -0
  141. data/lib/silkedit/images/silksong/Leaf_Glider.png +0 -0
  142. data/lib/silkedit/images/silksong/Leaf_Roller.png +0 -0
  143. data/lib/silkedit/images/silksong/Lost_Garmond.png +0 -0
  144. data/lib/silkedit/images/silksong/Lost_Lace.png +0 -0
  145. data/lib/silkedit/images/silksong/Maestro.png +0 -0
  146. data/lib/silkedit/images/silksong/Marrowmaw.png +0 -0
  147. data/lib/silkedit/images/silksong/Massive_Mossgrub.png +0 -0
  148. data/lib/silkedit/images/silksong/Mawling.png +0 -0
  149. data/lib/silkedit/images/silksong/Memoria.png +0 -0
  150. data/lib/silkedit/images/silksong/Minister.png +0 -0
  151. data/lib/silkedit/images/silksong/Miremite.png +0 -0
  152. data/lib/silkedit/images/silksong/Mite.png +0 -0
  153. data/lib/silkedit/images/silksong/Mitemother.png +0 -0
  154. data/lib/silkedit/images/silksong/Mnemonid.png +0 -0
  155. data/lib/silkedit/images/silksong/Mnemonord.png +0 -0
  156. data/lib/silkedit/images/silksong/Moorwing.png +0 -0
  157. data/lib/silkedit/images/silksong/Mortician.png +0 -0
  158. data/lib/silkedit/images/silksong/Moss_Mother.png +0 -0
  159. data/lib/silkedit/images/silksong/Mossgrub.png +0 -0
  160. data/lib/silkedit/images/silksong/Mossmir.png +0 -0
  161. data/lib/silkedit/images/silksong/Mothleaf_Lagnia.png +0 -0
  162. data/lib/silkedit/images/silksong/Muckmaggot.png +0 -0
  163. data/lib/silkedit/images/silksong/Muckroach.png +0 -0
  164. data/lib/silkedit/images/silksong/Nuphar.png +0 -0
  165. data/lib/silkedit/images/silksong/Nyleth.png +0 -0
  166. data/lib/silkedit/images/silksong/Overgrown_Pilgrim.png +0 -0
  167. data/lib/silkedit/images/silksong/Palestag.png +0 -0
  168. data/lib/silkedit/images/silksong/Pendra.png +0 -0
  169. data/lib/silkedit/images/silksong/Pendragor.png +0 -0
  170. data/lib/silkedit/images/silksong/Penitent.png +0 -0
  171. data/lib/silkedit/images/silksong/Phacia.png +0 -0
  172. data/lib/silkedit/images/silksong/Phantom.png +0 -0
  173. data/lib/silkedit/images/silksong/Pharlid.png +0 -0
  174. data/lib/silkedit/images/silksong/Pharlid_Diver.png +0 -0
  175. data/lib/silkedit/images/silksong/Pilgrim_Bellbearer.png +0 -0
  176. data/lib/silkedit/images/silksong/Pilgrim_Groveller.png +0 -0
  177. data/lib/silkedit/images/silksong/Pilgrim_Guide.png +0 -0
  178. data/lib/silkedit/images/silksong/Pilgrim_Hiker.png +0 -0
  179. data/lib/silkedit/images/silksong/Pilgrim_Hornfly.png +0 -0
  180. data/lib/silkedit/images/silksong/Pilgrim_Hulk.png +0 -0
  181. data/lib/silkedit/images/silksong/Pilgrim_Pouncer.png +0 -0
  182. data/lib/silkedit/images/silksong/Pinstress.png +0 -0
  183. data/lib/silkedit/images/silksong/Plasmid.png +0 -0
  184. data/lib/silkedit/images/silksong/Plasmidas.png +0 -0
  185. data/lib/silkedit/images/silksong/Plasmified_Zango.png +0 -0
  186. data/lib/silkedit/images/silksong/Pokenabbin.png +0 -0
  187. data/lib/silkedit/images/silksong/Pollenica.png +0 -0
  188. data/lib/silkedit/images/silksong/Pond_Skipper.png +0 -0
  189. data/lib/silkedit/images/silksong/Pondcatcher.png +0 -0
  190. data/lib/silkedit/images/silksong/Puny_Penitent.png +0 -0
  191. data/lib/silkedit/images/silksong/Reed.png +0 -0
  192. data/lib/silkedit/images/silksong/Rhinogrund.png +0 -0
  193. data/lib/silkedit/images/silksong/Roachcatcher.png +0 -0
  194. data/lib/silkedit/images/silksong/Roachfeeder.png +0 -0
  195. data/lib/silkedit/images/silksong/Roachkeeper.png +0 -0
  196. data/lib/silkedit/images/silksong/Roachserver.png +0 -0
  197. data/lib/silkedit/images/silksong/Sandcarver.png +0 -0
  198. data/lib/silkedit/images/silksong/Savage_Beastfly.png +0 -0
  199. data/lib/silkedit/images/silksong/Scabfly.png +0 -0
  200. data/lib/silkedit/images/silksong/Scrollreader.png +0 -0
  201. data/lib/silkedit/images/silksong/Second_Sentinel.png +0 -0
  202. data/lib/silkedit/images/silksong/Servitor_Boran.png +0 -0
  203. data/lib/silkedit/images/silksong/Servitor_Ignim.png +0 -0
  204. data/lib/silkedit/images/silksong/Shadow_Charger.png +0 -0
  205. data/lib/silkedit/images/silksong/Shadow_Creeper_(Silksong).png +0 -0
  206. data/lib/silkedit/images/silksong/Shardillard.png +0 -0
  207. data/lib/silkedit/images/silksong/Shellwood_Gnat.png +0 -0
  208. data/lib/silkedit/images/silksong/Shrine_Guardian_Seth.png +0 -0
  209. data/lib/silkedit/images/silksong/Silk_Snipper.png +0 -0
  210. data/lib/silkedit/images/silksong/Sister_Splinter.png +0 -0
  211. data/lib/silkedit/images/silksong/Skarr_Scout.png +0 -0
  212. data/lib/silkedit/images/silksong/Skarr_Stalker.png +0 -0
  213. data/lib/silkedit/images/silksong/Skarrgard.png +0 -0
  214. data/lib/silkedit/images/silksong/Skarrlid.png +0 -0
  215. data/lib/silkedit/images/silksong/Skarrsinger_Karmelita.png +0 -0
  216. data/lib/silkedit/images/silksong/Skarrwing.png +0 -0
  217. data/lib/silkedit/images/silksong/Skrill.png +0 -0
  218. data/lib/silkedit/images/silksong/Skull_Brute.png +0 -0
  219. data/lib/silkedit/images/silksong/Skull_Scuttler.png +0 -0
  220. data/lib/silkedit/images/silksong/Skull_Tyrant.png +0 -0
  221. data/lib/silkedit/images/silksong/Skullwing.png +0 -0
  222. data/lib/silkedit/images/silksong/Slubberlug.png +0 -0
  223. data/lib/silkedit/images/silksong/Smelt_Shoveller.png +0 -0
  224. data/lib/silkedit/images/silksong/Smokerock_Sifter.png +0 -0
  225. data/lib/silkedit/images/silksong/Snitchfly.png +0 -0
  226. data/lib/silkedit/images/silksong/Spear_Skarr.png +0 -0
  227. data/lib/silkedit/images/silksong/Spinebeak_Kai.png +0 -0
  228. data/lib/silkedit/images/silksong/Spit_Squit.png +0 -0
  229. data/lib/silkedit/images/silksong/Splinter.png +0 -0
  230. data/lib/silkedit/images/silksong/Splinterbark.png +0 -0
  231. data/lib/silkedit/images/silksong/Splinterhorn.png +0 -0
  232. data/lib/silkedit/images/silksong/Squatcraw.png +0 -0
  233. data/lib/silkedit/images/silksong/Squatcraw_Juror.png +0 -0
  234. data/lib/silkedit/images/silksong/Squirrm.png +0 -0
  235. data/lib/silkedit/images/silksong/Steelspine_Kai.png +0 -0
  236. data/lib/silkedit/images/silksong/Stilkin.png +0 -0
  237. data/lib/silkedit/images/silksong/Stilkin_Trapper.png +0 -0
  238. data/lib/silkedit/images/silksong/Summoned_Saviour.png +0 -0
  239. data/lib/silkedit/images/silksong/Surgeon.png +0 -0
  240. data/lib/silkedit/images/silksong/Swamp_Squit.png +0 -0
  241. data/lib/silkedit/images/silksong/Tallcraw.png +0 -0
  242. data/lib/silkedit/images/silksong/Tallcraw_Juror.png +0 -0
  243. data/lib/silkedit/images/silksong/Tarmite.png +0 -0
  244. data/lib/silkedit/images/silksong/The_Unravelled.png +0 -0
  245. data/lib/silkedit/images/silksong/Thread_Raker.png +0 -0
  246. data/lib/silkedit/images/silksong/Tormented_Trobbio.png +0 -0
  247. data/lib/silkedit/images/silksong/Trobbio.png +0 -0
  248. data/lib/silkedit/images/silksong/Undercrank.png +0 -0
  249. data/lib/silkedit/images/silksong/Underloft.png +0 -0
  250. data/lib/silkedit/images/silksong/Underpoke.png +0 -0
  251. data/lib/silkedit/images/silksong/Underscrub.png +0 -0
  252. data/lib/silkedit/images/silksong/Undersweep.png +0 -0
  253. data/lib/silkedit/images/silksong/Underworker.png +0 -0
  254. data/lib/silkedit/images/silksong/Vaultborn.png +0 -0
  255. data/lib/silkedit/images/silksong/Vaultkeeper.png +0 -0
  256. data/lib/silkedit/images/silksong/Verdanir.png +0 -0
  257. data/lib/silkedit/images/silksong/Vicious_Caranid.png +0 -0
  258. data/lib/silkedit/images/silksong/Void_Mass.png +0 -0
  259. data/lib/silkedit/images/silksong/Void_Tendrils_(Silksong).png +0 -0
  260. data/lib/silkedit/images/silksong/Voltvyrm.png +0 -0
  261. data/lib/silkedit/images/silksong/Wardenfly.png +0 -0
  262. data/lib/silkedit/images/silksong/Watcher_at_the_Edge.png +0 -0
  263. data/lib/silkedit/images/silksong/Widow.png +0 -0
  264. data/lib/silkedit/images/silksong/Winged_Furm.png +0 -0
  265. data/lib/silkedit/images/silksong/Winged_Lifeseed.png +0 -0
  266. data/lib/silkedit/images/silksong/Winged_Pilgrim.png +0 -0
  267. data/lib/silkedit/images/silksong/Winged_Pilgrim_Bellbearer.png +0 -0
  268. data/lib/silkedit/images/silksong/Wingmould_(Silksong).png +0 -0
  269. data/lib/silkedit/images/silksong/Wisp.png +0 -0
  270. data/lib/silkedit/images/silksong/Wood_Wasp.png +0 -0
  271. data/lib/silkedit/images/silksong/Wraith.png +0 -0
  272. data/lib/silkedit/images/silksong/Yago.png +0 -0
  273. data/lib/silkedit/images/silksong/Yuma.png +0 -0
  274. data/lib/silkedit/images/silksong/Yumama.png +0 -0
  275. data/lib/silkedit/savegame/crypto.rb +25 -0
  276. data/lib/silkedit/savegame/diff.rb +159 -0
  277. data/lib/silkedit/savegame/packer.rb +75 -0
  278. data/lib/silkedit/savegame/savefile.rb +157 -0
  279. data/lib/silkedit/util/system.rb +37 -0
  280. data/lib/silkedit/version.rb +5 -0
  281. data/lib/silkedit.rb +9 -0
  282. data/sig/silkedit.rbs +4 -0
  283. metadata +505 -0
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
data/exe/silkedit ADDED
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+ ################
4
+ ### Silkedit ###
5
+ ################
6
+
7
+ require 'rbcli'
8
+
9
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'silkedit')
10
+ Dir[File.join(File.dirname(__FILE__), '..', 'lib', 'config', '*.rb')].each { |file| require file }
11
+ Dir[File.join(File.dirname(__FILE__), '..', 'lib', 'commands', '*.rb')].each { |file| require file }
12
+
13
+ Rbcli.go!
@@ -0,0 +1,25 @@
1
+ Rbcli.command 'backup' do
2
+ description 'Backs up the savefile'
3
+ parameter :custom_name, 'Give the backup a custom name. Named backups can\'t be edited.', short: :n, type: :string
4
+ action do |opts, params, args, config, env|
5
+ s = Silkedit::Savegame::SaveFile.new(:silksong, opts[:savenum])
6
+ s.direct_backup(backup_name: params[:custom_name])
7
+ end
8
+ end
9
+
10
+ Rbcli.command 'restore' do
11
+ description 'Restore a backup to the savefile. Providing no parameters restores the latest backup.'
12
+ parameter :backup_seq, 'Backup number to restore (Can\'t use together with named backup)', short: :b, type: :integer
13
+ parameter :backup_name, 'Named backup to restore', short: :n, type: :string
14
+
15
+ action do |opts, params, args, config, env|
16
+ if !params[:backup_seq].nil? && !params[:backup_name].nil?
17
+ Rbcli.log.error 'Can\'t specify both a sequence and name at the same time.'
18
+ else
19
+ s = Silkedit::Savegame::SaveFile.new(:silksong, opts[:savenum])
20
+ unless s.direct_restore(seq_number: params[:backup_seq], backup_name: params[:backup_name])
21
+ Rbcli.log.error "Failed to restore backup"
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,74 @@
1
+ Rbcli.command 'cheat' do
2
+ description 'Applies one or more cheats to the selected savefile'
3
+ usage '<cheat1> <cheat2> <cheat3>...'
4
+ parameter :list, 'List all cheats', type: :bool, default: false
5
+ # parameter :force, "Force application of a cheat even when requirements aren't met. Additional changes may be made to your savegave.", type: :bool, default: false
6
+ action do |opts, params, args, config, env|
7
+ s = Silkedit::Savegame::SaveFile.new(:silksong, opts[:savenum])
8
+ s.load_from_dat
9
+ c = Silkedit::Cheat::Engine.new(s.data)
10
+
11
+ display_simple_list = lambda do |list, cols|
12
+ max_length = list.map(&:length).max
13
+ display_set = []
14
+ rows = (list.length / cols.to_f).ceil
15
+ row_idx = 0
16
+ max_rows = rows - 1
17
+ list.length.times do |i|
18
+ display_set[row_idx] ||= []
19
+ display_set[row_idx] << list[i]
20
+ row_idx += 1
21
+ row_idx = 0 if row_idx > max_rows
22
+ end
23
+ display_set.map { |row| row.map { |z| z.ljust(max_length) }.join(' ') }.join("\n")
24
+ end
25
+
26
+ if args.empty? || params[:list]
27
+ Rbcli.log.info 'Cheats:'
28
+ Rbcli.log.info display_simple_list.call(c.list_cheats, 5)
29
+ Rbcli.exit(0)
30
+ end
31
+
32
+ changes = args.map do |cht|
33
+ cht = cht.downcase
34
+ status = c.apply_cheat(cht)
35
+ case status
36
+ when :no_cheat
37
+ Rbcli.log.warn "Could not apply cheat #{cht}: Cheat does not exist"
38
+ Rbcli.log.info 'Did you mean one of these?'
39
+ possible_cheats = c.list_cheats.select { |cheat| cheat.include?(cht) }
40
+ Rbcli.log.info display_simple_list.call(possible_cheats, 5)
41
+ nil
42
+ when :failed_act_check
43
+ Rbcli.log.warn "Could not apply cheat #{cht.colorize(:red)}: The player is in the wrong act. Use --(f)orce to override."
44
+ nil
45
+ when :failed_soft_reqs
46
+ Rbcli.log.warn "Could not apply cheat #{cht.colorize(:red)}: Soft requirements not met. Use --(f)orce to apply the required changes."
47
+ nil
48
+ when :failed_hard_reqs
49
+ Rbcli.log.error "Could not apply cheat #{cht.colorize(:red)}: Hard requirements not met. Applying the cheat would cause in-game errors."
50
+ nil
51
+ when :success
52
+ Rbcli.log.info " Success!".colorize(:green)
53
+ cht
54
+ else
55
+ raise "Unknown status: #{status}"
56
+ end
57
+ end
58
+
59
+ if changes.empty?
60
+ Rbcli.log.info ''
61
+ Rbcli.log.info 'No cheats applied'
62
+ Rbcli.exit(0)
63
+ end
64
+
65
+ if changes.include?(nil)
66
+ Rbcli.log.info ''
67
+ Rbcli.log.info 'Some cheats failed to apply. Discarding changes.'
68
+ Rbcli.exit(0)
69
+ end
70
+
71
+ s.direct_backup
72
+ s.save_to_dat
73
+ end
74
+ end
@@ -0,0 +1,47 @@
1
+ Rbcli.command 'edit' do
2
+ description 'Edit the savefile directly'
3
+ action do |opts, params, args, config, env|
4
+ s = Silkedit::Savegame::SaveFile.new(:silksong, opts[:savenum])
5
+ s.load_from_dat
6
+ s.save_to_json
7
+ Process.wait(Process.spawn(config[:editor_command].sub('%FILE%', s.filenames[:json])))
8
+ if Silkedit::Sys.yes_no?('Apply changes?')
9
+ s.load_from_json
10
+ s.direct_backup
11
+ s.save_to_dat
12
+ Rbcli.log.info 'Updated savefile'
13
+ else
14
+ Rbcli.log.info 'Aborted'
15
+ end
16
+ end
17
+ end
18
+
19
+ Rbcli.command 'diff' do
20
+ description 'Diffs the current savegame against the latest backup, a specified backup, or a different save'
21
+ parameter :backup_seq, 'Backup number to diff against', short: :b, type: :integer
22
+ parameter :othersave, 'Other save number to diff against', short: :o, type: :integer
23
+ parameter :yaml_output, 'Output in YAML instead of a Ruby object', short: :y, type: :boolean
24
+
25
+
26
+ action do |opts, params, args, config, env|
27
+ new = Silkedit::Savegame::SaveFile.new(:silksong, opts[:savenum])
28
+ new.load_from_dat
29
+ if params[:othersave]
30
+ old = Silkedit::Savegame::SaveFile.new(:silksong, params[:othersave])
31
+ old.load_from_dat
32
+ else
33
+ old = Silkedit::Savegame::SaveFile.new(:silksong, opts[:savenum])
34
+ old.load_from_backup(seq_number: params[:backup_seq])
35
+ end
36
+
37
+ diff = Silkedit::Savegame::Diff.mkdiff(old.data, new.data)
38
+ Rbcli.log.info Silkedit::Savegame::Diff.parse_diff(diff, yaml_output: params[:yaml_output])
39
+
40
+ # s.save_as_json
41
+ # FileUtils.mv(s.json_filename, "#{s.json_filename}.old")
42
+ # s.load_from_dat
43
+ # s.save_as_json
44
+ # FileUtils.mv(s.json_filename, "#{s.json_filename}.new")
45
+ # Process.wait(Process.spawn(config[:diff_command].sub('%OLD%', "#{s.json_filename}.old").sub('%NEW%', "#{s.json_filename}.new")))
46
+ end
47
+ end
@@ -0,0 +1,51 @@
1
+ Rbcli.command "example" do
2
+ ##### Command Declaration (At least one is required) #####
3
+ # default (Optional) The default command is run when no other commands are called on the CLI
4
+ # Note that parameters are not available for default commands, as all CLI options
5
+ # are parsed against the global-level ones declared in the `Configurate.opts` block
6
+ # description (Optional) Short description that shows up in --help for the executable
7
+ # usage (Optional) Usage text that shows up in --help or when CLI format is bad
8
+ # helptext (Optional) Large help text that shows up in --help for the command
9
+ # default
10
+ description 'Example command'
11
+ usage "[--param|--otherparam] name"
12
+ helptext <<~EOF
13
+ Big block of helptext
14
+ EOF
15
+ # parameter (Optinoal) Parameters follow the same format as CLI Options, but are only available for this command
16
+ parameter :param, 'A Parameter', default: false
17
+ parameter :otherparam, 'Another Parameter', type: :string, default: "Default value"
18
+ # action (Required, unless declaring a `script`) The action block is code that gets executed when the command is called
19
+ # Sending all output through the logger is recommended. For it to be displayed
20
+ # as regular text, set the logger to the :display format
21
+ action do |opts, params, args, config, env|
22
+ Rbcli.log.info "Welcome to your new application!"
23
+ Rbcli.log.info "We like to send all of our output through the logger for easy formatting and deployment..."
24
+ puts "...but you don't have to"
25
+ Rbcli.log.info "Here's a quick demo of how to use the framework:\n"
26
+
27
+ Rbcli.log.info "Top-level CLI Options: " + opts.to_s
28
+ Rbcli.log.info "Parameters: " + params.to_s
29
+ Rbcli.log.info "Arguments on the CLI: " + args.to_s
30
+ Rbcli.log.info "The config: " + config.to_s
31
+ Rbcli.log.info "Environment variables: " + env.to_s
32
+ Rbcli.log.info ""
33
+
34
+ Rbcli.log.debug "Example Debug Message (change your log level to see this!)", "MYAPP"
35
+ Rbcli.log.info "Example Info Message", "MYAPP"
36
+ Rbcli.log.warn "Example Warning Message", "MYAPP"
37
+ Rbcli.log.error "Example Error Message", "MYAPP"
38
+ Rbcli.log.fatal "Example Fatal Message", "MYAPP"
39
+ Rbcli.log.unknown "Example Unknown Message", "MYAPP"
40
+ Rbcli.log.info ""
41
+
42
+ config.add_default :foo, 'bar'
43
+ config.create!
44
+ config.load!
45
+ config[:davey] = 'Davey Jones'.compress
46
+ Rbcli.log.info "Compressed String: " + config[:davey]
47
+ Rbcli.log.info "Decompressed String: " + config[:davey].decompress
48
+ config.save!
49
+ Rbcli.log.info config
50
+ end
51
+ end
@@ -0,0 +1,36 @@
1
+ # Script Command
2
+ # Supports all of the same features as a regular command, but passes everything to a bash script
3
+ # The script can be defined inline, or a path to an external script can be provided
4
+ #
5
+ # Code is injected into the script to integrate with Rbcli.
6
+ # The `log` commands are integrated with the ruby logger
7
+ # The `rbcli` command provides a wrapper around jq that can retrieve
8
+ # the values of opts/params/args/config/env
9
+ # For more information on JQ syntax, see: https://jqlang.github.io/jq/
10
+ Rbcli.command "script" do
11
+ description "example script command"
12
+ # external_script vars: {}, path: "./test.sh"
13
+ inline_script vars: { foo: 'bar!!!' }, inline: <<~INLINE
14
+ #!/usr/bin/env bash
15
+ log "Rbcli shell integration demo!"
16
+ log "A custom JQ wrapper is used to parse config passed through from Rbcli"
17
+ log "For more information on how to use it, see: https://jqlang.github.io/jq/"
18
+ log ""
19
+
20
+ log "Top-level CLI Options: $(rbcli opts .)"
21
+ log "Parameters: $(rbcli params .)"
22
+ log "Arguments on the CLI: $(rbcli args .)"
23
+ log "Config: $(rbcli config .)"
24
+ log "Environment Variables: $(rbcli env .)"
25
+ log "Custom Var from command: $(rbcli vars .foo)"
26
+ log "Same variable, in environment: ${FOO}"
27
+
28
+ log "Logs are integrated too"
29
+ log "Example Debug (you need to change your log level to see this)" "debug"
30
+ log "Example Info" "info"
31
+ log "Example Warning" "warn"
32
+ log "Example Error" "error"
33
+ log "Example Fatal" "fatal"
34
+ log "Example Unknown" "unknown"
35
+ INLINE
36
+ end
@@ -0,0 +1,34 @@
1
+ Rbcli.command 'journal' do
2
+ description 'Manages the journal of enemy kills'
3
+ usage '[listall|listmissing|complete|killsonly]'
4
+ parameter :showimages, 'Show images of the enemies', short: 'i', type: :bool, default: false
5
+ action do |opts, params, args, config, env|
6
+ command = args.first
7
+ if command.nil? || command.empty? || !%w[listall listmissing complete killsonly].include?(command)
8
+ Rbcli.log.error "Must specify an action as one of: listall, listmissing, complete, killsonly"
9
+ next
10
+ end
11
+
12
+ s = Silkedit::Savegame::SaveFile.new(:silksong, opts[:savenum])
13
+ s.load_from_dat
14
+ c = Silkedit::Cheat::Engine.new(s.data)
15
+
16
+ case command
17
+ when 'listall'
18
+ c.enemy_list(only_missing: false, show_images: params[:showimages])
19
+ when 'listmissing'
20
+ c.enemy_list(only_missing: true, show_images: params[:showimages])
21
+ when 'complete'
22
+ c.update_journal(should_update_kills_only: false)
23
+ s.direct_backup
24
+ s.save_to_dat
25
+ when 'killsonly'
26
+ c.update_journal(should_update_kills_only: true)
27
+ s.direct_backup
28
+ s.save_to_dat
29
+ else
30
+ Rbcli.fatal "Unknown command: #{command}", exit_status: 1
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,62 @@
1
+ Rbcli.command 'permasave' do
2
+ description 'Saves a local copy of a game into the config to restore later.'
3
+ parameter :name, 'Name to give the savegame', short: :n, type: :string, required: true
4
+ action do |opts, params, args, config, env|
5
+ permasave_file = config[:permasave_file_location][Silkedit::Sys.os]
6
+ permasave_file = permasave_file.gsub('%APPDATA%', ENV['APPDATA'] || ENV['LOCALAPPDATA']) if Silkedit::Sys.os == :windows
7
+ permasave_file = File.expand_path(permasave_file)
8
+ unless File.exist?(permasave_file)
9
+ FileUtils.cp(File.join(Silkedit::LIBDIR, 'config', 'silksong', 'permasaves.yaml'), permasave_file)
10
+ end
11
+ permasaves = YAML.safe_load_file(permasave_file)
12
+ Rbcli.log.fatal('Permasaves file is corrupt. Please delete or fix it and try again.', exit_status: 1) unless permasaves.is_a?(Hash)
13
+
14
+ params[:name] = params[:name].downcase
15
+ if permasaves.key?(params[:name])
16
+ Rbcli.log.warn "Found existing permasave: #{params[:name]}"
17
+ next unless Silkedit::Sys.yes_no?('Overwrite?')
18
+ end
19
+
20
+ s = Silkedit::Savegame::SaveFile.new(:silksong, opts[:savenum])
21
+ s.load_from_dat
22
+ permasaves[params[:name]] = YAML.safe_dump(s.data).compress
23
+ File.write(permasave_file, YAML.safe_dump(permasaves))
24
+
25
+ Rbcli.log.info "Permasave #{params[:name]} saved from slot #{opts[:savenum]}"
26
+ end
27
+ end
28
+
29
+ Rbcli.command 'permaload' do
30
+ description 'Restores a permasave into the slot'
31
+ parameter :name, 'Name of the permasave to load', short: :n, type: :string, required: false
32
+ parameter :list, 'List all permasaves', short: :l, type: :bool, default: false
33
+ action do |opts, params, args, config, env|
34
+ permasave_file = config[:permasave_file_location][Silkedit::Sys.os]
35
+ permasave_file = permasave_file.gsub('%APPDATA%', ENV['APPDATA'] || ENV['LOCALAPPDATA']) if Silkedit::Sys.os == :windows
36
+ permasave_file = File.expand_path(permasave_file)
37
+ unless File.exist?(permasave_file)
38
+ FileUtils.cp(File.join(Silkedit::LIBDIR, 'config', 'silksong', 'permasaves.yaml'), permasave_file)
39
+ end
40
+ permasaves = YAML.safe_load_file(permasave_file)
41
+ Rbcli.log.fatal('Permasaves file is corrupt. Please delete or fix it and try again.', exit_status: 1) unless permasaves.is_a?(Hash)
42
+
43
+ if !params[:name] && !params[:list]
44
+ Rbcli.log.warn 'Must provide a permasave name to load, or use --(l)ist to list all permasaves.'
45
+ next
46
+ elsif params[:list]
47
+ Rbcli.log.info permasaves.keys.join("\n")
48
+ next
49
+ end
50
+ params[:name] = params[:name].downcase
51
+
52
+ s = Silkedit::Savegame::SaveFile.new(:silksong, opts[:savenum])
53
+ if permasaves.is_a?(Hash) && permasaves.key?(params[:name])
54
+ s.data = YAML.safe_load(permasaves[params[:name]].decompress)
55
+ s.data['profileID'] = opts[:savenum].to_i
56
+ s.save_to_dat
57
+ Rbcli.log.info "Permasave #{params[:name]} loaded to slot #{opts[:savenum]}."
58
+ else
59
+ Rbcli.log.warn "Permasave #{params[:name]} does not exist. Exiting."
60
+ end
61
+ end
62
+ end
File without changes
@@ -0,0 +1,27 @@
1
+ Rbcli.command 'unpack' do
2
+ description 'Unpacks a save file or backup to JSON/YAML for manual editing'
3
+ parameter :backup_seq, 'Sequence number for the backup to unpack', short: :b, type: :integer
4
+ action do |opts, params, args, config, env|
5
+ s = Silkedit::Savegame::SaveFile.new(:silksong, opts[:savenum])
6
+ if params[:backup_seq].nil?
7
+ s.load_from_dat
8
+ s.save_to_json
9
+ Rbcli.log.info 'Unpacked savefile to json/yaml'
10
+ else
11
+ s.load_from_backup(seq_number: params[:backup_seq])
12
+ s.save_to_json
13
+ Rbcli.log.info "Unpacked backup ##{params[:backup_seq]}"
14
+ end
15
+ end
16
+ end
17
+
18
+ Rbcli.command 'repack' do
19
+ description 'Packs the JSON/YAML to the savefile'
20
+ action do |opts, params, args, config, env|
21
+ s = Silkedit::Savegame::SaveFile.new(:silksong, opts[:savenum])
22
+ s.load_from_json
23
+ s.direct_backup
24
+ s.save_to_dat
25
+ Rbcli.log.info 'Repacked savefile from json/yaml'
26
+ end
27
+ end
@@ -0,0 +1,103 @@
1
+ Rbcli.command 'zone' do
2
+ description 'Zones the character to a different respawn point'
3
+ usage '<zone> (--(f)orce)'
4
+ parameter :list, 'Display the full list of zones to select from', type: :bool, default: false
5
+ parameter :force, 'Force select a spawn point even when requirements are not met. Changes may be made to your savegave.', type: :bool, default: false
6
+ action do |opts, params, args, config, env|
7
+ s = Silkedit::Savegame::SaveFile.new(:silksong, opts[:savenum])
8
+ s.load_from_dat
9
+ c = Silkedit::Cheat::Engine.new(s.data)
10
+
11
+ display_simple_list = lambda do |list, cols|
12
+ max_length = list.map(&:length).max
13
+ display_set = []
14
+ rows = (list.length / cols.to_f).ceil
15
+ row_idx = 0
16
+ max_rows = rows - 1
17
+ list.length.times do |i|
18
+ display_set[row_idx] ||= []
19
+ display_set[row_idx] << list[i]
20
+ row_idx += 1
21
+ row_idx = 0 if row_idx > max_rows
22
+ end
23
+ display_set.map { |row| row.map { |z| z.ljust(max_length) }.join(' ') }.join("\n")
24
+ end
25
+
26
+ display_detailed_zone_list = lambda do |list|
27
+ max_shortcut_length = list.map { |zone| (zone[:shortcut] || '').length }.max
28
+ formatter = "%-#{max_shortcut_length}s %3s %s"
29
+ final_string = ''
30
+ final_string << format(formatter, 'Shortcut', 'Act', 'Zone') + "\n"
31
+ final_string << list.map { |zone| format(formatter, zone[:shortcut], zone[:min_act], zone[:slug]) }.join("\n")
32
+ final_string
33
+ end
34
+
35
+ if args.empty? || params[:list]
36
+ Rbcli.log.info 'Shortcuts:'
37
+ Rbcli.log.info display_simple_list.call(c.list_shortcuts.keys, 5)
38
+ end
39
+
40
+ if params[:list]
41
+ Rbcli.log.info ''
42
+ Rbcli.log.info 'Zones:'
43
+ Rbcli.log.info display_detailed_zone_list.call(c.list_zones)
44
+ end
45
+
46
+ Rbcli.exit(0) if args.empty? || params[:list]
47
+
48
+ status = c.zone_to(args.first, force_soft_reqs: params[:force], enforce_min_act: !params[:force])
49
+ case status
50
+ when :no_zone
51
+ Rbcli.log.warn "Could not zone to #{args.first}: Specified spawn point does not exist"
52
+ Rbcli.log.info 'Did you mean one of these?'
53
+ possible_zones = c.list_zones.select { |zone| zone[:slug].include?(args.first) || !zone[:shortcut].nil? && zone[:shortcut].include?(args.first) }
54
+ Rbcli.log.info display_detailed_zone_list.call(possible_zones, 5)
55
+ when :failed_act_check
56
+ Rbcli.log.warn "Could not zone to #{args.first.colorize(:red)}: The player is in the wrong act. Use --(f)orce to override."
57
+ when :failed_soft_reqs
58
+ Rbcli.log.warn "Could not zone to #{args.first.colorize(:red)}: Soft requirements not met. Use --(f)orce to apply the required changes."
59
+ when :failed_hard_reqs
60
+ Rbcli.log.error "Could not zone to #{args.first.colorize(:red)}: Hard requirements not met. Zoning here would cause in-game errors."
61
+ when :success
62
+ s.direct_backup
63
+ s.save_to_dat
64
+ Rbcli.log.info "Zoned to #{args.first.colorize(:green)}"
65
+ else
66
+ raise "Unknown status: #{status}"
67
+ end
68
+ end
69
+ end
70
+
71
+ Rbcli.command 'mkzone' do
72
+ description 'Adds a new spawn point to the library'
73
+ usage '<slug>'
74
+ parameter :slug, 'The slug of the zone to add', type: :string
75
+ parameter :act, 'Override default act detection', type: :integer
76
+ parameter :shortcut, 'Provide a shorter slug as a shortcut for the zone', short: 'o', type: :string
77
+ parameter :force, 'Force overwrite of existing zone', type: :bool, default: false
78
+ action do |opts, params, args, config, env|
79
+ if params[:slug].nil?
80
+ Rbcli.log.error 'Must provide a zone slug'
81
+ next
82
+ end
83
+
84
+ s = Silkedit::Savegame::SaveFile.new(:silksong, opts[:savenum])
85
+ s.load_from_dat
86
+ c = Silkedit::Cheat::Engine.new(s.data)
87
+
88
+ status = c.save_current_zone(params[:slug], params[:shortcut], params[:act], overwrite: params[:force])
89
+
90
+ case status
91
+ when :badname
92
+ Rbcli.log.error 'Invalid zone name. Zones must be formatted as: region.target'
93
+ when :badact
94
+ Rbcli.log.error 'Invalid act number. Act must be between 1 and 3, or leave blank for autodetection.'
95
+ when :badshortcut
96
+ Rbcli.log.error 'Invalid shortcut. Shortcuts must not have a period (.) in them.'
97
+ when :success
98
+ Rbcli.log.info "Added #{params[:slug]} to zonelist."
99
+ else
100
+ Rbcli.log.error "Duplicate zone found: #{status}. Use --(f)orce to overwrite."
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,28 @@
1
+ Rbcli::Configurate.config do
2
+ ##### Config (Optional) #####
3
+ # The built-in config will automatically pull in a config file to a hash and vice versa
4
+ # It can either be used immutably (as user-defined configuration) and/or to store application state
5
+ #
6
+ # file: <string> or <array> (Required) Provide either a specific config file location or a hierarchy to search. If creating a :null type of config this can be omitted.
7
+ # type: (:yaml|:json|:ini|:toml|:null) (Optional) Select which backend/file format to use. If the file has an associated extension (i.e. '.yaml') then this can be omitted.
8
+ # schema_file: <string> (Optional) The file location of a JSON Schema (https://json-schema.org). If provided, the config will automatically be validated. (default: nil)
9
+ # schema_hash: <string> (Optional) If you'd like to provide a JSON schema hash directly instead, do it here. May not use `schema_hash` and `schema_file` together. (default: nil)
10
+ # save_on_exit: (true|false) (Optional) Save changes to the config file on exit (default: false)
11
+ # create_if_not_exists: (true|false) (Optional) Create the file using default values if it is not found on the system (default: false)
12
+ # suppress_errors: (true|false) (Optional) If set to false, the application will halt on any errors in loading the config. If set to true, defaults will be provided (default: true)
13
+ # banner: <string> (Optional) Define a banner to be placed at the top of the config file on disk. Note that it will only be written to backends that support comments
14
+ # defaults: <hash> (Optional) Defaults set here will be provided to your application if any values are missing in the config.
15
+ # They will also be used to create new config files when the flag `create_if_not_exists` is set to true.
16
+ # skeleton: <string> (Optional) If a skeleton is provided, it will be used as the config source when creating new config files on disk instead of the defaults. (default: nil)`
17
+ # Please provide the text exactly as you want the user to see it in the config file (plus the banner if provided).
18
+ file [File.join(Silkedit::LIBDIR, 'config', 'silkedit.yaml')]
19
+ type :yaml
20
+ # schema_file nil
21
+ # schema_hash nil
22
+ save_on_exit false
23
+ create_if_not_exists false
24
+ suppress_errors true
25
+ # banner nil
26
+ # defaults({ editor_command: "vi '%FILE%'", permasaves: {} })
27
+ # skeleton "eJzT1dXlSsvPt1JISiziAhFWSYlVAD1hBjs=".decompress
28
+ end
@@ -0,0 +1,23 @@
1
+ Rbcli::Configurate.envvars do
2
+ ##### Environment Variable Parsing (Optional) #####
3
+ # The envvars module can pull in all environment variables with a given
4
+ # prefix and organize them into a hash structure based on name.
5
+ # It will also parse the string values and convert them to the proper type (Integer, Boolean, etc)
6
+ # Any values set here will be treated as defaults and made available when a variable is missing
7
+ #
8
+ # For example, these two environment variables:
9
+ # SILKEDIT_TERM_HEIGHT=40
10
+ # SILKEDIT_TERM_WIDTH=120
11
+ # Would be declared here as:
12
+ # prefix 'SILKEDIT'
13
+ # envvar 'TERM_HEIGHT', 40
14
+ # envvar 'TERM_WIDTH', 120
15
+ # And get loaded into the env hash as:
16
+ # { term: { height: 40, width: 120 } }
17
+ #
18
+ # If the prefix is unset or equal to nil, the environment variables specified here will
19
+ # be loaded without one.
20
+ prefix 'SILKEDIT'
21
+ envvar 'SAVENUM', nil
22
+ envvar 'DEVELOPMENT', false
23
+ end
@@ -0,0 +1,22 @@
1
+ Rbcli::Configurate.hooks do
2
+ ##### Hooks (Optional) #####
3
+ # These hooks are scheduled on the Rbcli execution engine to run
4
+ # Pre- and Post- the command specified. They are executed after
5
+ # everything else has been initialized, so the runtime configuration
6
+ # values are all made available, as they will appear to the command.
7
+ #
8
+ # These are good for parsing and/or doing transformations on the provided
9
+ # configuration before passing them to the command, and for cleaning
10
+ # up your environment afterwards.
11
+ pre_execute do |opts, params, args, config, env|
12
+ opts[:savenum] = env[:savenum] if opts[:savenum].nil? && !env[:savenum].nil?
13
+
14
+ if !opts[:savenum].is_a?(Integer) || opts[:savenum] < 1 || opts[:savenum] > 4
15
+ Rbcli.log.fatal 'A savegame index between 1-4 must be specified either via the command line (-s #) or environment variable (SILKEDIT_SAVENUM=#). See help (-h) for details.', exit_status: 24
16
+ end
17
+ end
18
+
19
+ # post_execute do |opts, params, args, config, env|
20
+ # Rbcli.log.info "I'm done running the command!"
21
+ # end
22
+ end
@@ -0,0 +1,36 @@
1
+ Rbcli::Configurate.logger do
2
+ ##### Logger (Optional) #####
3
+ # The Rbcli logger is a wrapper around the standard Ruby `Logger` library
4
+ # It is recommended that - unless you want to use specialized output libraries (such as ncurses) - that all
5
+ # of your application output is directed through the logger. This will allow for easy formatting and redirection
6
+ # no matter how your application is run.
7
+ #
8
+ # Valid targets are: :stdout, :stderr, "/path/to/a/file", or an IO or StringIO object (Default: :stdout)
9
+ # Valid levels are: :debug, :info, :warn, :error, :fatal, :unknown, :any (Default: :info)
10
+ # Valid formats are: :display, :simple, :full, :ruby, :json, :apache, :lolcat (Default: :display)
11
+ #
12
+ # The first three formats are designed to cover most use cases:
13
+ # display: For display on a terminal, with user interaction
14
+ # simple: For display on a terminal, for a developer
15
+ # full: For logging to a file, or using log collection software
16
+ # The next three are for specialized integrations in case you already have log collection configured:
17
+ # ruby: Default ruby logger format
18
+ # json: Each line is a JSON object
19
+ # apache: Follows the standard Apache log format
20
+ # As for :lolcat... if you can't guess what it does then give it a shot
21
+ logger target: :stdout, level: :info, format: :display
22
+ # Custom formats can also be defined here.
23
+ # Declaring a format here will not switch to it. However, if
24
+ # the `format` keyword is used without providing a Proc, it will switch
25
+ # to that format.
26
+ #
27
+ # Format switch: format :json
28
+ # Format definition: format :foo, Proc.new { |severity, datetime, progname, msg| "Foo! " + msg }
29
+ #
30
+ # You can also switch formats mid-execution by calling this method on
31
+ # the logger object itself.
32
+ #
33
+ # Rbcli.log.format :json
34
+ #
35
+ # format :foo, Proc.new { |severity, datetime, progname, msg| "Foo! " + msg }
36
+ end
@@ -0,0 +1,34 @@
1
+ Rbcli::Configurate.cli do
2
+ ##### Core Configuration (Required) #####
3
+ # appname (Optional) - Defaults to the name of the executable
4
+ # author (Optional) - A name or array of names
5
+ # email (Optional) - An email for users to contact
6
+ # version (Optional) - major.minor.patch notation, required if using update checks
7
+ # copyright_year (Optional) - Self explanatory
8
+ # compatibility (Optional) - Array of Operating Systems, devices, or other targets (For example: %w[MacOS Linux Ubuntu Windows Raspberry\ Pi]
9
+ # license (Optional) - Convention is to use an identifier from here: https://spdx.org/licenses/
10
+ # helptext (Optional) - Text that gets shown with --help or -h
11
+ appname nil
12
+ author ['Andrew Khoury']
13
+ email nil
14
+ version Silkedit::VERSION
15
+ copyright_year 2025
16
+ compatibility %w[MacOS Linux]
17
+ license 'GPL-3.0'
18
+ helptext 'This is a tool to quickly and easily edit savefiles for SilkSong.'
19
+ ##### CLI Options (Optional) #####
20
+ # These appear to commands as `opts`.
21
+ # Format:
22
+ # opt :name, "Description"[, optional arguments ]
23
+ # Optional Arguments:
24
+ # long: Specify the long form (--long) version of an argument. (Default: same as the name)
25
+ # short: Specify the short form (-s) version of an argument. (Default: first letter of the name)
26
+ # type: Specify the type. Valid options are :boolean, :float, :integer, :string, :io, :date. (Default: :boolean)
27
+ # If the plural form of any of the above are used (i.e. ':strings') then the user can provide a comma-delimited list on the command line (--param=foo,bar)
28
+ # required: If set to true, requires that this option is provided by the user. (Default: false)
29
+ # multi: If set to true, allows the option to be provided multiple times (--param --param, or in short form, -pp). (Default: false)
30
+ # When using this with a :boolean type, rather than returning `true` or `false`, it will return a count of the number of times the parameter was passed.
31
+ # permitted: If set to an array, restricts input to the values within that array. (Default: nil (no restrictions))
32
+ # opt :verbose, "Twice or more enables very-verbose output", multi: true
33
+ opt :savenum, "A number from 1-4, indicating which game save you'd like to address", short: 's', type: :integer
34
+ end
@@ -0,0 +1,12 @@
1
+ Rbcli::Configurate.updatechecker do
2
+ ##### Update Check (Optional) #####
3
+ # The application can warn users when a new version is released
4
+ # Checks can be done either by rubygems or by a Github repo
5
+ # Private servers for Github (enterprise) are supported
6
+ #
7
+ # Setting force_update to true will halt execution until it is updated
8
+ #
9
+ # For Github, an access_token is required for private repos. See: https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens
10
+ # gem 'silkedit', force_update: false, message: 'Please run `gem update silkedit` to upgrade to the latest version.'
11
+ # github 'repo/name', access_token: nil, enterprise_hostname: nil, force_update: false, message: 'Please download the latest version from Github'
12
+ end