smc-get 0.2.0.beta1 → 0.3.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,10 +1,10 @@
1
- #!/usr/bin/env ruby
2
- #Encoding: UTF-8
3
-
4
- module SmcGet
5
-
6
- class Repository
7
-
8
- end
9
-
1
+ #!/usr/bin/env ruby
2
+ #Encoding: UTF-8
3
+
4
+ module SmcGet
5
+
6
+ class Repository
7
+
8
+ end
9
+
10
10
  end
@@ -1,117 +1,118 @@
1
- #Encoding: UTF-8
2
- ################################################################################
3
- # This file is part of smc-get.
4
- # Copyright (C) 2010-2011 Entertaining Software, Inc.
5
- # Copyright (C) 2011 Marvin Gülker
6
- #
7
- # This program is free software: you can redistribute it and/or modify
8
- # it under the terms of the GNU General Public License as published by
9
- # the Free Software Foundation, either version 3 of the License, or
10
- # (at your option) any later version.
11
- #
12
- # This program is distributed in the hope that it will be useful,
13
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
- # GNU General Public License for more details.
16
- #
17
- # You should have received a copy of the GNU General Public License
18
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
- ################################################################################
20
-
21
- require "pathname"
22
- require 'tempfile'
23
- require "fileutils"
24
- require "tempfile"
25
- require "digest/sha1"
26
- begin
27
- require "psych"
28
- rescue LoadError
29
- end
30
- require "yaml"
31
- require 'uri'
32
- require "open-uri"
33
- require 'net/https'
34
- require "archive/tar/minitar"
35
- require "xz"
36
-
37
- require_relative "./errors"
38
- require_relative "./repository"
39
- require_relative "./local_repository"
40
- require_relative "./remote_repository"
41
- require_relative "./package_archive"
42
- require_relative "./package_specification"
43
- require_relative "./package"
44
-
45
- #Extend the Hash class with a method to turn all keys into symbols.
46
- class Hash
47
-
48
- #Recursively turns all keys in this hash into symbols. This method
49
- #is inteded for loading configuration files. Doesn’t modify the receiver.
50
- def symbolic_keys
51
- inject({}){|hsh, (k, v)| hsh[k.to_sym] = v.respond_to?(:symbolic_keys) ? v.symbolic_keys : v; hsh}
52
- end
53
-
54
- end
55
-
56
- #This is the main module of smc-get and it's namespace.
57
- module SmcGet
58
-
59
- #Root directory of the smc-get program and libraries.
60
- ROOT_DIR = Pathname.new(__FILE__).dirname.parent.parent
61
- #Subdirectory for executable files.
62
- BIN_DIR = ROOT_DIR + "bin"
63
- #Subdirectory for library files.
64
- LIB_DIR = ROOT_DIR + "lib"
65
- #Subdirectory for configuration files.
66
- CONFIG_DIR = ROOT_DIR + "config"
67
-
68
- #Directory where the package specifications are saved to. Relative to the
69
- #data directory in SmcGet.datadir.
70
- PACKAGE_SPECS_DIR = "packages".freeze
71
- #Directory where a package's music files are saved to. Relative to the
72
- #data directory in SmcGet.datadir.
73
- PACKAGE_MUSIC_DIR = "music/contrib-music".freeze
74
- #Directory where a package's graphics files are saved to. Relative to the
75
- #data directory given in SmcGet.datadir
76
- PACKAGE_GRAPHICS_DIR = "pixmaps/contrib-graphics".freeze
77
- #Directory where a package's level files are saved to. Relative to the
78
- #data directory given in SmcGet.datadir.
79
- PACKAGE_LEVELS_DIR = "levels".freeze
80
- #The name of the file containing the list of all levels in the
81
- #repository.
82
- PACKAGE_LIST_FILE = "#{PACKAGE_SPECS_DIR}/packages.lst".freeze
83
- #The version of smc-get.
84
- Pathname.new(__FILE__).dirname.expand_path.join("..", "..", "VERSION.txt").read.match(/\A(\d+)\.(\d+)\.(\d+)(\-.*?)?\Z/)
85
- VERSION = {
86
- :mayor => $1.to_i,
87
- :minor => $2.to_i,
88
- :tiny => $3.to_i,
89
- :dev => $4,
90
- }
91
-
92
- class << self
93
-
94
- #The temporary directory used by smc-get.
95
- attr_reader :temp_dir
96
-
97
- #Initializes the library.
98
- def setup
99
- @temp_dir = Pathname.new(Dir.mktmpdir("smc-get"))
100
- at_exit{@temp_dir.rmtree}
101
- VERSION.freeze #Nobody changes this after initializing anymore!
102
- end
103
-
104
- #Returns smc-get's version by concatenating the VERSION constant's
105
- #values in a sensible mannor. Return value is a string of form
106
- # mayor.minor.tiny[-dev|-rc|-beta1|...] (<date>, commit <commit_num>)
107
- def version
108
- str = "#{VERSION[:mayor]}.#{VERSION[:minor]}.#{VERSION[:tiny]}"
109
- str << VERSION[:dev] if VERSION[:dev]
110
- str
111
- end
112
-
113
- end
114
-
115
- end
116
-
117
- # vim:set ts=8 sts=2 sw=2 et: #
1
+ #Encoding: UTF-8
2
+ ################################################################################
3
+ # This file is part of smc-get.
4
+ # Copyright (C) 2010-2011 Entertaining Software, Inc.
5
+ # Copyright (C) 2011 Marvin Gülker
6
+ #
7
+ # This program is free software: you can redistribute it and/or modify
8
+ # it under the terms of the GNU General Public License as published by
9
+ # the Free Software Foundation, either version 3 of the License, or
10
+ # (at your option) any later version.
11
+ #
12
+ # This program is distributed in the hope that it will be useful,
13
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
+ # GNU General Public License for more details.
16
+ #
17
+ # You should have received a copy of the GNU General Public License
18
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
19
+ ################################################################################
20
+
21
+ require "pathname"
22
+ require 'tempfile'
23
+ require "fileutils"
24
+ require "tempfile"
25
+ require "digest/sha1"
26
+ require "webrick"
27
+ begin
28
+ require "psych"
29
+ rescue LoadError
30
+ end
31
+ require "yaml"
32
+ require 'uri'
33
+ require "open-uri"
34
+ require 'net/https'
35
+ require "archive/tar/minitar"
36
+ require "xz"
37
+
38
+ require_relative "./errors"
39
+ require_relative "./repository"
40
+ require_relative "./local_repository"
41
+ require_relative "./remote_repository"
42
+ require_relative "./package_archive"
43
+ require_relative "./package_specification"
44
+ require_relative "./package"
45
+
46
+ #Extend the Hash class with a method to turn all keys into symbols.
47
+ class Hash
48
+
49
+ #Recursively turns all keys in this hash into symbols. This method
50
+ #is inteded for loading configuration files. Doesn’t modify the receiver.
51
+ def symbolic_keys
52
+ inject({}){|hsh, (k, v)| hsh[k.to_sym] = v.respond_to?(:symbolic_keys) ? v.symbolic_keys : v; hsh}
53
+ end
54
+
55
+ end
56
+
57
+ #This is the main module of smc-get and it's namespace.
58
+ module SmcGet
59
+
60
+ #Root directory of the smc-get program and libraries.
61
+ ROOT_DIR = Pathname.new(__FILE__).dirname.parent.parent
62
+ #Subdirectory for executable files.
63
+ BIN_DIR = ROOT_DIR + "bin"
64
+ #Subdirectory for library files.
65
+ LIB_DIR = ROOT_DIR + "lib"
66
+ #Subdirectory for configuration files.
67
+ CONFIG_DIR = ROOT_DIR + "config"
68
+
69
+ #Directory where the package specifications are saved to. Relative to the
70
+ #data directory in SmcGet.datadir.
71
+ PACKAGE_SPECS_DIR = "packages".freeze
72
+ #Directory where a package's music files are saved to. Relative to the
73
+ #data directory in SmcGet.datadir.
74
+ PACKAGE_MUSIC_DIR = "music/contrib-music".freeze
75
+ #Directory where a package's graphics files are saved to. Relative to the
76
+ #data directory given in SmcGet.datadir
77
+ PACKAGE_GRAPHICS_DIR = "pixmaps/contrib-graphics".freeze
78
+ #Directory where a package's level files are saved to. Relative to the
79
+ #data directory given in SmcGet.datadir.
80
+ PACKAGE_LEVELS_DIR = "levels".freeze
81
+ #The name of the file containing the list of all levels in the
82
+ #repository.
83
+ PACKAGE_LIST_FILE = "#{PACKAGE_SPECS_DIR}/packages.lst".freeze
84
+ #The version of smc-get.
85
+ Pathname.new(__FILE__).dirname.expand_path.join("..", "..", "VERSION.txt").read.match(/\A(\d+)\.(\d+)\.(\d+)(\-.*?)?\Z/)
86
+ VERSION = {
87
+ :mayor => $1.to_i,
88
+ :minor => $2.to_i,
89
+ :tiny => $3.to_i,
90
+ :dev => $4,
91
+ }
92
+
93
+ class << self
94
+
95
+ #The temporary directory used by smc-get.
96
+ attr_reader :temp_dir
97
+
98
+ #Initializes the library.
99
+ def setup
100
+ @temp_dir = Pathname.new(Dir.mktmpdir("smc-get"))
101
+ at_exit{@temp_dir.rmtree}
102
+ VERSION.freeze #Nobody changes this after initializing anymore!
103
+ end
104
+
105
+ #Returns smc-get's version by concatenating the VERSION constant's
106
+ #values in a sensible mannor. Return value is a string of form
107
+ # mayor.minor.tiny[-dev|-rc|-beta1|...] (<date>, commit <commit_num>)
108
+ def version
109
+ str = "#{VERSION[:mayor]}.#{VERSION[:minor]}.#{VERSION[:tiny]}"
110
+ str << VERSION[:dev] if VERSION[:dev]
111
+ str
112
+ end
113
+
114
+ end
115
+
116
+ end
117
+
118
+ # vim:set ts=8 sts=2 sw=2 et: #
@@ -1,332 +1,332 @@
1
- = Secret Maryo Chronicles Package specification
2
-
3
- This file describes how Secret Maryo Chronicles Packages are defined.
4
- They allow for easy deployment and uploading to an online repository which
5
- we have not yet created, but are going to do soon!
6
-
7
- == Contents
8
-
9
- 1. General
10
- 2. File format
11
- 3. Levels format
12
- 4. Worlds format
13
- 5. Graphics format
14
- 6. Sounds and music format
15
- 7. README.txt format
16
- 8. Specification format
17
- 1. Package specification structure
18
- 9. About versions and updates
19
- 10. Repositories
20
- 1. Repository layout
21
- 2. packages.lst format
22
- 3. Repository example
23
-
24
- == General
25
-
26
- * The files have the extension <tt>.smcpak</tt>.
27
- * The files are xz-compressed tarballs.
28
- * The filename may not contain whitespace.
29
-
30
- == File format
31
-
32
- mypackage.smcpak/
33
- - README.txt
34
- - mypackage.yml
35
- levels/
36
- - Level1.smclvl
37
- - Level1_sublevel.smclvl
38
- - Levelsetname_01Level1.smclvl
39
- - Levelsetname_01Level1_sublevel.smclvl
40
- worlds/
41
- world1/
42
- - description.xml
43
- - layer.xml
44
- - world.xml
45
- pixmaps/
46
- - graphic1.png
47
- - graphic2.png
48
- sounds/
49
- - sound1.ogg
50
- - sound2.ogg
51
- music/
52
- - music1.ogg
53
- - music2.ogg
54
-
55
- == Levels format
56
-
57
- * A Level must be named after one of the following conventions:
58
-
59
- [Levelname.smclvl] This is the simplest way to name a level. If your
60
- package just contains one level or several ones that aren't
61
- related to each other, use this convention.
62
- [Level1_sublevel.smclvl] Same as the previous convention, but your levels
63
- have sublevels. Prefix the sublevel with the
64
- main level's name and an underscore.
65
- [Levelsetname_xxLevel1.smclvl] This is the convention you want to use if you
66
- have multiple levels related to each other, e.g.
67
- they just follow one another or are combined
68
- in an overworld. Prefix the levels' names with
69
- the levelset's name, an underscore, and then
70
- a 2-digit number indicating in which order
71
- the levels should be played.
72
- [Levelsetname_xxLevel1_sublevel.smclvl] The same as the previous convention,
73
- but the levels have sublevels. Just
74
- append an underscore to the previous
75
- convention, then put the sublevel's
76
- name.
77
-
78
- * None of the conventions allows for whitespace in the level names. Use
79
- underscores if necessary.
80
-
81
- == Worlds format
82
-
83
- * We don't have any assumptions about how you name your worlds, but
84
- * do not use whitespace in their names.
85
-
86
- == Graphics format
87
-
88
- * Graphics are in the PNG (Portable Network Graphics) format.
89
- * Their names don't contain whitespace.
90
- * They may reside in subfolders.
91
-
92
- == Sounds and music format
93
-
94
- * They are in OGG (OGG Theora) format.
95
- * Their names don't contain whitespace.
96
- * They may reside in subfolders.
97
-
98
- == README.txt format
99
-
100
- * The filename is always <tt>README.txt</tt>.
101
- * Don't offend anybody in your README.
102
- * Everything else is up to you.
103
-
104
- == Specification format
105
-
106
- The package specifiaction is the main file of the package and you should pay close attention to it.
107
-
108
- * The file is in YAML format (Yet Another Markup Language).
109
- * The filename is always the same as the package name (*not* as the title,
110
- i.e. if the title is "My Package" and you name the package
111
- "mypackage.smcpak", then the spec must be named "mypackage.yml").
112
-
113
- The general structure is as follows:
114
-
115
- === Package specification structure
116
-
117
- ---
118
- title: "TITLE OF YOUR PACKAGE"
119
- last_update: 2011-01-23 15:48:00Z
120
- authors:
121
- - Author1
122
- - Author2
123
- difficulty: "DIFFICULTY"
124
- dependencies:
125
- - package1
126
- - package2
127
- description: >
128
- An arbitrary long description of your package that can
129
- span multiple lines.
130
- install_message: >
131
- A message to print to the terminal after the package has been installed.
132
- It may span multiple lines and you're free to ommit this option at all.
133
- remove_message: >
134
- A message to print to the terminal after the package has been removed.
135
- It may span multiple lines and you're free to ommit this option at all.
136
- levels:
137
- - lvl1.smclvl
138
- - lvl2.smclvl
139
- graphics:
140
- - pic1.png
141
- - pic2.png
142
- music:
143
- - music1.ogg
144
- - music2.ogg
145
- sounds:
146
- - sound1.ogg
147
- - sound2.ogg
148
- worlds:
149
- - world1
150
- - world2
151
- checksums:
152
- levels:
153
- lvl1.smclvl: <checksum>
154
- lvl2.smclvl: <checksum>
155
- graphics:
156
- pic1.png: <checksum>
157
- pic2.png: <checksum>
158
- music:
159
- music1.ogg: <checksum>
160
- music2.ogg: <checksum>
161
- sounds:
162
- sound1.ogg: <checksum>
163
- sound2.ogg: <checksum>
164
- worlds:
165
- world1:
166
- description.xml: <checksum>
167
- layer.xml: <checksum>
168
- world.xml: <checksum>
169
- world2:
170
- description.xml: <checksum>
171
- layer.xml: <checksum>
172
- world.xml: <checksum>
173
-
174
- * The +title+ may not be longer than 80 characters. It can contain whitespace.
175
- This field is mandatory.
176
- * The +last_update+ field is used by <tt>smc-get</tt> in order to find out weather or
177
- not a package needs to be updated. Fill this with your last modification time in YAML
178
- format, preferably using UTC instead of your local timezone which would have the
179
- following format:
180
- YYYY-MM-DD hh:mm:ssZ
181
- The terminating +Z+ is meant literally, i.e. if you’re using UTC it has to be in the
182
- final format string. See the sample specification above for an example.
183
- * The list of +authors+ can be arbitrary long, but must contain at least
184
- one entry. This field is mandatory.
185
- * The +difficulty+ can be anything you like, but we encourage you to use
186
- one of the following ones:
187
- * easy
188
- * medium
189
- * hard
190
- * unknown
191
- * You *have* to put +difficulty+, even if you just put +unknown+ as the value.
192
- * The +dependencies+ list contains of an arbitrary long list of package names
193
- that have to be installed before this package can be installed. Use this
194
- sparingly, because users don't want to end up with 100 packages be installed
195
- for a single one. If possible, ommit it at all.
196
- * The +descripton+ field is mandatory. It contains a multiline description
197
- of what this package contains.
198
- * The +install_message+ field is optional. See the above figure for further
199
- explanation.
200
- * The +remove_message+ field is optional. See the above figure for further
201
- explanation.
202
- * The +levels+, +graphics+, +music+, +sounds+ and +worlds+ fields are all
203
- optional, but it makes sense to include at least one of them. They state
204
- which files in your directories actually belong to the package. For each
205
- option, you specify file paths relative to a directory named the same
206
- as the option (e.g. files you list under "levels" reside in a "levels"
207
- directory in your package's root directory). An exception is +worlds+,
208
- where you specify directory paths rather than file paths.
209
- * All fields under the +checksums+ field are mandatory. They contain the
210
- (hex-encoded) SHA1 checksums of all important files in the package.
211
-
212
- The multiline fields can have two different formats that affect how
213
- newlines are treated. The first format you already saw is this one:
214
-
215
- desc: >
216
- Newlines that are placed here, like the following
217
- do not show up in the output.
218
-
219
- Note that the output won't have a newline after the world "following". The
220
- second form is this one:
221
-
222
- desc: |
223
- Newlines that are placed here, like the following
224
- do show up in the output.
225
-
226
- This time the output will have a newline after the word "following". We don't
227
- recommand one form over the other, but keep in mind that using the first
228
- form may better fit large terminals, whereas the second form allows you
229
- to prevent cutting words in the middle for line breaking (assuming a
230
- standard 80-characters wide terminal).
231
-
232
- == About versions and updates
233
-
234
- <tt>smc-get</tt> doesn't have a concept of versions. During install,
235
- <tt>smc-get</tt> writes the installation date into a special file, allowing
236
- you to alter the levels downloaded without corrupting it's date. Then, when
237
- you run <tt>smc-get update</tt>, <tt>smc-get</tt> checks wheather the
238
- modification times of the package files in the repository are newer than
239
- the installation date it remembered previously. If it finds one or more
240
- packages that fulfill this requirement, they will be uninstalled and the
241
- newer package will be downloaded and installed. If <tt>smc-get</tt> detects
242
- changes have been made to the levels contained in the package, it will
243
- ask you if you want to lose them by overwriting the levels with the new
244
- version from the repository, or if the modified level should be moved to
245
- a new file with the name <tt>levelname.MODIFIED.smclvl</tt>.
246
-
247
- == Repositories
248
-
249
- The main repository's URL is not clear as of now (2nd April 2011), but is
250
- likely to be somewhere on Sourceforge.net. This is the repository
251
- <tt>smc-get</tt> accesses by default, and you'll find that it contains only
252
- the compressed packages. If you want to download individual files bypassing
253
- <tt>smc-get</tt>, you can have a look at the "source repository" at
254
- https://github.com/Luiji/Secret-Maryo-Chronicles-Contributed-Levels . All
255
- files contained in that repository are collected and compressed to packages
256
- by means of an automated process (hopefully) and then uploaded to the main
257
- repository at sourceforge.
258
-
259
- === Repository layout
260
-
261
- A repository's access type is unimportant, <tt>smc-get</tt> will handle
262
- FTP, HTTP and HTTPS all reasonably well. The directory structure of a repository
263
- is the thing where you have to pay close attention to, otherwise
264
- <tt>smc-get</tt> will complain and fail. This is what the URIs should look like:
265
-
266
- http://your_host.org/smc-repo
267
- /packages
268
- /specs
269
- /packages.lst
270
-
271
- * The +packages+ sub-uri contains the actual packages, tar-xz files ending in
272
- <tt>.smcpak</tt>, as discussed earlier in this document.
273
- * The +specs+ sub-uri contains the package specifications of all the packages
274
- in the +packages+ dir, uncompressed to faciliate searching for specific
275
- attributes of a package. They obey the same format as the normal package
276
- specifications discussed earlier, and in fact, they *are* the same
277
- specifications.
278
- * The <tt>packages.lst</tt> file contains a list of all packages the repository
279
- contains. The format is described below.
280
-
281
- For instance, if the user wanted <tt>smc-get</tt> to download <tt>mypackage</tt>
282
- from your repository, <tt>smc-get</tt> would perform the following queries:
283
-
284
- 1. <tt>GET http://your_host.org/smc-repo/packages.lst</tt>. This is to check if
285
- the repository even contains the package.
286
- 2. <tt>GET http://your_host.org/smc-repo/packages/mypackage.smcpak</tt>. This
287
- is the actual download operation.
288
-
289
- Or, if the user wants to search for a package whose description contains
290
- "this is cool" <tt>smc-get</tt> would act like this:
291
-
292
- 1. <tt>GET http://your_host.org/smc-repo/packages.lst</tt>. This is to get a
293
- list of all packages the repository contains.
294
- 2. <tt>GET http://your_host.org/smc-repo/specs/firstspec.yml</tt>. The first
295
- package's specification mentioned in your <tt>packages.lst</tt> gets
296
- downloaded. If it contains the search query "this is cool", <tt>smc-get</tt>
297
- provides the user with some information and then continues with the next
298
- specification, and so on, until either the user stops the process or all
299
- package specifications have been queried.
300
-
301
- === packages.lst format
302
-
303
- This file is a simple text file that contains one package name per line. For
304
- example, if your repository contains the packages "mypackage.smcpak" and
305
- "mygroup/my2ndpackage.smcpak", the file would look like this:
306
-
307
- mypackage
308
- mygroup/my2ndpackage
309
-
310
- Note that the file extension <tt>.smcpak</tt> is ommited.
311
-
312
- === Repository example
313
-
314
- Suppose your repository contains the packages "cool_level", "myworld", and
315
- "incredible_levels/hyper1". The URIs your repository provides should look
316
- like this:
317
-
318
- http://your_host.org/smc-repo/packages/cool_level.smcpak
319
- http://your_host.org/smc-repo/packages/myworld.smcpak
320
- http://your_host.org/smc-repo/packages/incredible_levels/hyper1.smcpak
321
-
322
- http://your_host.org/smc-repo/specs/cool_level.yml
323
- http://your_host.org/smc-repo/specs/myworld.yml
324
- http://your_host.org/smc-repo/specs/incredible_levels/hyper1.yml
325
-
326
- http://your_host.org/smc-repo/packages.lst
327
-
328
- and the <tt>packages.lst</tt> should look like this:
329
-
330
- cool_level
331
- myworld
1
+ = Secret Maryo Chronicles Package specification
2
+
3
+ This file describes how Secret Maryo Chronicles Packages are defined.
4
+ They allow for easy deployment and uploading to an online repository which
5
+ we have not yet created, but are going to do soon!
6
+
7
+ == Contents
8
+
9
+ 1. General
10
+ 2. File format
11
+ 3. Levels format
12
+ 4. Worlds format
13
+ 5. Graphics format
14
+ 6. Sounds and music format
15
+ 7. README.txt format
16
+ 8. Specification format
17
+ 1. Package specification structure
18
+ 9. About versions and updates
19
+ 10. Repositories
20
+ 1. Repository layout
21
+ 2. packages.lst format
22
+ 3. Repository example
23
+
24
+ == General
25
+
26
+ * The files have the extension <tt>.smcpak</tt>.
27
+ * The files are xz-compressed tarballs.
28
+ * The filename may not contain whitespace.
29
+
30
+ == File format
31
+
32
+ mypackage.smcpak/
33
+ - README.txt
34
+ - mypackage.yml
35
+ levels/
36
+ - Level1.smclvl
37
+ - Level1_sublevel.smclvl
38
+ - Levelsetname_01Level1.smclvl
39
+ - Levelsetname_01Level1_sublevel.smclvl
40
+ worlds/
41
+ world1/
42
+ - description.xml
43
+ - layer.xml
44
+ - world.xml
45
+ pixmaps/
46
+ - graphic1.png
47
+ - graphic2.png
48
+ sounds/
49
+ - sound1.ogg
50
+ - sound2.ogg
51
+ music/
52
+ - music1.ogg
53
+ - music2.ogg
54
+
55
+ == Levels format
56
+
57
+ * A Level must be named after one of the following conventions:
58
+
59
+ [Levelname.smclvl] This is the simplest way to name a level. If your
60
+ package just contains one level or several ones that aren't
61
+ related to each other, use this convention.
62
+ [Level1_sublevel.smclvl] Same as the previous convention, but your levels
63
+ have sublevels. Prefix the sublevel with the
64
+ main level's name and an underscore.
65
+ [Levelsetname_xxLevel1.smclvl] This is the convention you want to use if you
66
+ have multiple levels related to each other, e.g.
67
+ they just follow one another or are combined
68
+ in an overworld. Prefix the levels' names with
69
+ the levelset's name, an underscore, and then
70
+ a 2-digit number indicating in which order
71
+ the levels should be played.
72
+ [Levelsetname_xxLevel1_sublevel.smclvl] The same as the previous convention,
73
+ but the levels have sublevels. Just
74
+ append an underscore to the previous
75
+ convention, then put the sublevel's
76
+ name.
77
+
78
+ * None of the conventions allows for whitespace in the level names. Use
79
+ underscores if necessary.
80
+
81
+ == Worlds format
82
+
83
+ * We don't have any assumptions about how you name your worlds, but
84
+ * do not use whitespace in their names.
85
+
86
+ == Graphics format
87
+
88
+ * Graphics are in the PNG (Portable Network Graphics) format.
89
+ * Their names don't contain whitespace.
90
+ * They may reside in subfolders.
91
+
92
+ == Sounds and music format
93
+
94
+ * They are in OGG (OGG Theora) format.
95
+ * Their names don't contain whitespace.
96
+ * They may reside in subfolders.
97
+
98
+ == README.txt format
99
+
100
+ * The filename is always <tt>README.txt</tt>.
101
+ * Don't offend anybody in your README.
102
+ * Everything else is up to you.
103
+
104
+ == Specification format
105
+
106
+ The package specifiaction is the main file of the package and you should pay close attention to it.
107
+
108
+ * The file is in YAML format (Yet Another Markup Language).
109
+ * The filename is always the same as the package name (*not* as the title,
110
+ i.e. if the title is "My Package" and you name the package
111
+ "mypackage.smcpak", then the spec must be named "mypackage.yml").
112
+
113
+ The general structure is as follows:
114
+
115
+ === Package specification structure
116
+
117
+ ---
118
+ title: "TITLE OF YOUR PACKAGE"
119
+ last_update: 2011-01-23 15:48:00Z
120
+ authors:
121
+ - Author1
122
+ - Author2
123
+ difficulty: "DIFFICULTY"
124
+ dependencies:
125
+ - package1
126
+ - package2
127
+ description: >
128
+ An arbitrary long description of your package that can
129
+ span multiple lines.
130
+ install_message: >
131
+ A message to print to the terminal after the package has been installed.
132
+ It may span multiple lines and you're free to ommit this option at all.
133
+ remove_message: >
134
+ A message to print to the terminal after the package has been removed.
135
+ It may span multiple lines and you're free to ommit this option at all.
136
+ levels:
137
+ - lvl1.smclvl
138
+ - lvl2.smclvl
139
+ graphics:
140
+ - pic1.png
141
+ - pic2.png
142
+ music:
143
+ - music1.ogg
144
+ - music2.ogg
145
+ sounds:
146
+ - sound1.ogg
147
+ - sound2.ogg
148
+ worlds:
149
+ - world1
150
+ - world2
151
+ checksums:
152
+ levels:
153
+ lvl1.smclvl: <checksum>
154
+ lvl2.smclvl: <checksum>
155
+ graphics:
156
+ pic1.png: <checksum>
157
+ pic2.png: <checksum>
158
+ music:
159
+ music1.ogg: <checksum>
160
+ music2.ogg: <checksum>
161
+ sounds:
162
+ sound1.ogg: <checksum>
163
+ sound2.ogg: <checksum>
164
+ worlds:
165
+ world1:
166
+ description.xml: <checksum>
167
+ layer.xml: <checksum>
168
+ world.xml: <checksum>
169
+ world2:
170
+ description.xml: <checksum>
171
+ layer.xml: <checksum>
172
+ world.xml: <checksum>
173
+
174
+ * The +title+ may not be longer than 80 characters. It can contain whitespace.
175
+ This field is mandatory.
176
+ * The +last_update+ field is used by <tt>smc-get</tt> in order to find out weather or
177
+ not a package needs to be updated. Fill this with your last modification time in YAML
178
+ format, preferably using UTC instead of your local timezone which would have the
179
+ following format:
180
+ YYYY-MM-DD hh:mm:ssZ
181
+ The terminating +Z+ is meant literally, i.e. if you’re using UTC it has to be in the
182
+ final format string. See the sample specification above for an example.
183
+ * The list of +authors+ can be arbitrary long, but must contain at least
184
+ one entry. This field is mandatory.
185
+ * The +difficulty+ can be anything you like, but we encourage you to use
186
+ one of the following ones:
187
+ * easy
188
+ * medium
189
+ * hard
190
+ * unknown
191
+ * You *have* to put +difficulty+, even if you just put +unknown+ as the value.
192
+ * The +dependencies+ list contains of an arbitrary long list of package names
193
+ that have to be installed before this package can be installed. Use this
194
+ sparingly, because users don't want to end up with 100 packages be installed
195
+ for a single one. If possible, ommit it at all.
196
+ * The +descripton+ field is mandatory. It contains a multiline description
197
+ of what this package contains.
198
+ * The +install_message+ field is optional. See the above figure for further
199
+ explanation.
200
+ * The +remove_message+ field is optional. See the above figure for further
201
+ explanation.
202
+ * The +levels+, +graphics+, +music+, +sounds+ and +worlds+ fields are all
203
+ optional, but it makes sense to include at least one of them. They state
204
+ which files in your directories actually belong to the package. For each
205
+ option, you specify file paths relative to a directory named the same
206
+ as the option (e.g. files you list under "levels" reside in a "levels"
207
+ directory in your package's root directory). An exception is +worlds+,
208
+ where you specify directory paths rather than file paths.
209
+ * All fields under the +checksums+ field are mandatory. They contain the
210
+ (hex-encoded) SHA1 checksums of all important files in the package.
211
+
212
+ The multiline fields can have two different formats that affect how
213
+ newlines are treated. The first format you already saw is this one:
214
+
215
+ desc: >
216
+ Newlines that are placed here, like the following
217
+ do not show up in the output.
218
+
219
+ Note that the output won't have a newline after the world "following". The
220
+ second form is this one:
221
+
222
+ desc: |
223
+ Newlines that are placed here, like the following
224
+ do show up in the output.
225
+
226
+ This time the output will have a newline after the word "following". We don't
227
+ recommand one form over the other, but keep in mind that using the first
228
+ form may better fit large terminals, whereas the second form allows you
229
+ to prevent cutting words in the middle for line breaking (assuming a
230
+ standard 80-characters wide terminal).
231
+
232
+ == About versions and updates
233
+
234
+ <tt>smc-get</tt> doesn't have a concept of versions. During install,
235
+ <tt>smc-get</tt> writes the installation date into a special file, allowing
236
+ you to alter the levels downloaded without corrupting it's date. Then, when
237
+ you run <tt>smc-get update</tt>, <tt>smc-get</tt> checks wheather the
238
+ modification times of the package files in the repository are newer than
239
+ the installation date it remembered previously. If it finds one or more
240
+ packages that fulfill this requirement, they will be uninstalled and the
241
+ newer package will be downloaded and installed. If <tt>smc-get</tt> detects
242
+ changes have been made to the levels contained in the package, it will
243
+ ask you if you want to lose them by overwriting the levels with the new
244
+ version from the repository, or if the modified level should be moved to
245
+ a new file with the name <tt>levelname.MODIFIED.smclvl</tt>.
246
+
247
+ == Repositories
248
+
249
+ The main repository's URL is not clear as of now (2nd April 2011), but is
250
+ likely to be somewhere on Sourceforge.net. This is the repository
251
+ <tt>smc-get</tt> accesses by default, and you'll find that it contains only
252
+ the compressed packages. If you want to download individual files bypassing
253
+ <tt>smc-get</tt>, you can have a look at the "source repository" at
254
+ https://github.com/Luiji/Secret-Maryo-Chronicles-Contributed-Levels . All
255
+ files contained in that repository are collected and compressed to packages
256
+ by means of an automated process (hopefully) and then uploaded to the main
257
+ repository at sourceforge.
258
+
259
+ === Repository layout
260
+
261
+ A repository's access type is unimportant, <tt>smc-get</tt> will handle
262
+ FTP, HTTP and HTTPS all reasonably well. The directory structure of a repository
263
+ is the thing where you have to pay close attention to, otherwise
264
+ <tt>smc-get</tt> will complain and fail. This is what the URIs should look like:
265
+
266
+ http://your_host.org/smc-repo
267
+ /packages
268
+ /specs
269
+ /packages.lst
270
+
271
+ * The +packages+ sub-uri contains the actual packages, tar-xz files ending in
272
+ <tt>.smcpak</tt>, as discussed earlier in this document.
273
+ * The +specs+ sub-uri contains the package specifications of all the packages
274
+ in the +packages+ dir, uncompressed to faciliate searching for specific
275
+ attributes of a package. They obey the same format as the normal package
276
+ specifications discussed earlier, and in fact, they *are* the same
277
+ specifications.
278
+ * The <tt>packages.lst</tt> file contains a list of all packages the repository
279
+ contains. The format is described below.
280
+
281
+ For instance, if the user wanted <tt>smc-get</tt> to download <tt>mypackage</tt>
282
+ from your repository, <tt>smc-get</tt> would perform the following queries:
283
+
284
+ 1. <tt>GET http://your_host.org/smc-repo/packages.lst</tt>. This is to check if
285
+ the repository even contains the package.
286
+ 2. <tt>GET http://your_host.org/smc-repo/packages/mypackage.smcpak</tt>. This
287
+ is the actual download operation.
288
+
289
+ Or, if the user wants to search for a package whose description contains
290
+ "this is cool" <tt>smc-get</tt> would act like this:
291
+
292
+ 1. <tt>GET http://your_host.org/smc-repo/packages.lst</tt>. This is to get a
293
+ list of all packages the repository contains.
294
+ 2. <tt>GET http://your_host.org/smc-repo/specs/firstspec.yml</tt>. The first
295
+ package's specification mentioned in your <tt>packages.lst</tt> gets
296
+ downloaded. If it contains the search query "this is cool", <tt>smc-get</tt>
297
+ provides the user with some information and then continues with the next
298
+ specification, and so on, until either the user stops the process or all
299
+ package specifications have been queried.
300
+
301
+ === packages.lst format
302
+
303
+ This file is a simple text file that contains one package name per line. For
304
+ example, if your repository contains the packages "mypackage.smcpak" and
305
+ "mygroup/my2ndpackage.smcpak", the file would look like this:
306
+
307
+ mypackage
308
+ mygroup/my2ndpackage
309
+
310
+ Note that the file extension <tt>.smcpak</tt> is ommited.
311
+
312
+ === Repository example
313
+
314
+ Suppose your repository contains the packages "cool_level", "myworld", and
315
+ "incredible_levels/hyper1". The URIs your repository provides should look
316
+ like this:
317
+
318
+ http://your_host.org/smc-repo/packages/cool_level.smcpak
319
+ http://your_host.org/smc-repo/packages/myworld.smcpak
320
+ http://your_host.org/smc-repo/packages/incredible_levels/hyper1.smcpak
321
+
322
+ http://your_host.org/smc-repo/specs/cool_level.yml
323
+ http://your_host.org/smc-repo/specs/myworld.yml
324
+ http://your_host.org/smc-repo/specs/incredible_levels/hyper1.yml
325
+
326
+ http://your_host.org/smc-repo/packages.lst
327
+
328
+ and the <tt>packages.lst</tt> should look like this:
329
+
330
+ cool_level
331
+ myworld
332
332
  incredible_levels/hyper1