stormlib 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5ff524f86ea0c9e2858245236c5a4d4502025a2fe14b41e16b9931023ddb883e
4
+ data.tar.gz: 4ffdd628e17b275e0808ad71c0b13f1dcd196ec37227e53cecd5853342fcaecc
5
+ SHA512:
6
+ metadata.gz: adb233f5be9efa2df1605cbda608eb4333aca0d97606b26a902a88af86763df94867ca56e275347dd3394e054a5af18993682b10fd72067b03c3b0fbd9c31911
7
+ data.tar.gz: e00b1bf12ff95a9ef4e940ae89a7efde73eac922f6d5d4ef75b0907d1813d6c1ca6b03a9f7f1eee01773400a8c426b66c19c2e8b8de4515b29ff8c8bd7614e09
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2024-09-21
4
+
5
+ - Initial release
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 sebi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,84 @@
1
+ # StormLib ๐ŸŒช๏ธ
2
+
3
+ StormLib is a Ruby gem that provides a wrapper for the [StormLib C++ library](https://github.com/ladislav-zezula/StormLib), allowing you to work with MPQ (Mo'PaQ) archives in your Ruby projects for World of Warcraft and other Blizzard games.
4
+
5
+ ## ๐Ÿ“ฆ Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'stormlib'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ ```
16
+ $ bundle install
17
+ ```
18
+
19
+ Or install it yourself as:
20
+
21
+ ```
22
+ $ gem install stormlib
23
+ ```
24
+
25
+ ## ๐Ÿ› ๏ธ Dependencies
26
+
27
+ Before installing the gem, make sure you have the following dependencies installed on your system:
28
+
29
+ - zlib1g-dev
30
+ - libbz2-dev
31
+ - build-essential
32
+ - libstdc++-12-dev
33
+
34
+ You can install these on Ubuntu or Debian-based systems with:
35
+
36
+ ```
37
+ $ sudo apt-get install zlib1g-dev libbz2-dev build-essential libstdc++-12-dev
38
+ ```
39
+
40
+ ## ๐Ÿš€ Usage
41
+
42
+ Here are some examples of how to use StormLib:
43
+
44
+ ```ruby
45
+ require 'stormlib'
46
+
47
+ # Open an existing MPQ archive
48
+ archive = StormLib::Archive.new('game.mpq')
49
+
50
+ # List files in the archive
51
+ files = archive.list_files
52
+ puts "Files in the archive: #{files.join(', ')}"
53
+
54
+ # Extract a file from the archive
55
+ archive.extract_file('readme.txt', 'extracted_readme.txt')
56
+
57
+ # Create a new MPQ archive
58
+ new_archive = StormLib::Archive.new('new_archive.mpq', create: true)
59
+
60
+ # Add a file to the new archive
61
+ new_archive.add_file('local_file.txt', 'archived_file.txt')
62
+
63
+ # Don't forget to close the archives when you're done
64
+ archive.close
65
+ new_archive.close
66
+ ```
67
+
68
+ ## ๐Ÿงช Development
69
+
70
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
71
+
72
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
73
+
74
+ ## ๐Ÿค Contributing
75
+
76
+ Bug reports and pull requests are welcome on GitHub at https://github.com/sebyx07/stormlib. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/sebyx07/stormlib/blob/master/CODE_OF_CONDUCT.md).
77
+
78
+ ## ๐Ÿ“œ License
79
+
80
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
81
+
82
+ ## ๐Ÿ‘ฅ Code of Conduct
83
+
84
+ Everyone interacting in the StormLib project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/sebyx07/stormlib/blob/master/CODE_OF_CONDUCT.md).
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+
5
+ def log(message)
6
+ puts "[extconf.rb] #{message}"
7
+ end
8
+
9
+ log 'Checking for StormLib...'
10
+ STORMLIB_DIR = File.expand_path('../StormLib', __FILE__)
11
+
12
+ if File.directory?(STORMLIB_DIR) && File.exist?(File.join(STORMLIB_DIR, 'src', 'StormLib.h'))
13
+ log 'StormLib found!'
14
+ else
15
+ log "Cannot find StormLib directory in #{STORMLIB_DIR}"
16
+
17
+ system "git clone https://github.com/ladislav-zezula/StormLib.git #{STORMLIB_DIR}" or raise 'Failed to clone StormLib'
18
+ end
19
+
20
+ # Compile StormLib
21
+ Dir.chdir(STORMLIB_DIR) do
22
+ log 'Configuring StormLib with CMake...'
23
+ system('cmake . -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_C_FLAGS="-Wno-old-style-definition" -DBUILD_SHARED_LIBS=OFF') or raise 'Failed to configure StormLib with CMake'
24
+
25
+ log 'Cleaning previous build...'
26
+ system('make clean') or log 'Warning: make clean failed, but continuing...'
27
+
28
+ log 'Building StormLib...'
29
+ system('make') or raise 'Failed to build StormLib'
30
+ end
31
+
32
+ # Find the library file
33
+ lib_file = Dir.glob("#{STORMLIB_DIR}/**/{libstorm.a,libstorm.so}").first
34
+
35
+ if lib_file.nil?
36
+ raise "Cannot find libstorm.a or libstorm.so in #{STORMLIB_DIR}"
37
+ end
38
+
39
+ lib_dir = File.dirname(lib_file)
40
+ lib_name = File.basename(lib_file).sub(/^lib/, '').sub(/\.(a|so)$/, '')
41
+
42
+ log "Found StormLib: #{lib_file}"
43
+
44
+ require 'mkmf'
45
+
46
+ # Set up the extension
47
+ $CFLAGS << " -I#{STORMLIB_DIR}/src -fPIC"
48
+ $LDFLAGS << " -L#{lib_dir} -l#{lib_name} -lz -lbz2 -lstdc++"
49
+
50
+ # Adjust the library path
51
+ $LDFLAGS << " -Wl,-rpath,#{lib_dir}"
52
+
53
+ # Ensure the compiler can find necessary headers and libraries
54
+ dir_config('stormlib', "#{STORMLIB_DIR}/src", lib_dir)
55
+
56
+ unless have_library(lib_name)
57
+ log "Unable to find #{lib_name} library. Contents of #{lib_dir}:"
58
+ Dir.foreach(lib_dir) { |f| log " #{f}" }
59
+ raise "Unable to find #{lib_name} library"
60
+ end
61
+
62
+ unless have_library('z')
63
+ log 'Trying to find zlib in system directories...'
64
+ raise 'Unable to find zlib' unless find_library('z', 'deflate')
65
+ end
66
+
67
+ unless have_library('bz2')
68
+ log 'Trying to find bzip2 in system directories...'
69
+ raise 'Unable to find bzip2 library' unless find_library('bz2', 'BZ2_bzCompress')
70
+ end
71
+
72
+ # Create the makefile
73
+ log 'Creating Makefile...'
74
+ create_makefile('stormlib/stormlib')
75
+
76
+ log 'extconf.rb completed successfully'
@@ -0,0 +1,92 @@
1
+ #include <ruby.h>
2
+ #include <StormLib.h>
3
+
4
+ static VALUE rb_SFileCreateArchive(VALUE self, VALUE filename, VALUE flags, VALUE max_file_count) {
5
+ HANDLE hMpq;
6
+ const char* szFileName = StringValueCStr(filename);
7
+ DWORD dwFlags = NUM2ULONG(flags);
8
+ DWORD dwMaxFileCount = NUM2ULONG(max_file_count);
9
+
10
+ if (SFileCreateArchive(szFileName, dwFlags, dwMaxFileCount, &hMpq)) {
11
+ return ULONG2NUM((uintptr_t)hMpq);
12
+ } else {
13
+ rb_raise(rb_eRuntimeError, "Failed to create archive");
14
+ }
15
+ }
16
+
17
+ static VALUE rb_SFileOpenArchive(VALUE self, VALUE filename, VALUE priority, VALUE flags) {
18
+ HANDLE hMpq;
19
+ const char* szFileName = StringValueCStr(filename);
20
+ DWORD dwPriority = NUM2ULONG(priority);
21
+ DWORD dwFlags = NUM2ULONG(flags);
22
+
23
+ if (SFileOpenArchive(szFileName, dwPriority, dwFlags, &hMpq)) {
24
+ return ULONG2NUM((uintptr_t)hMpq);
25
+ } else {
26
+ rb_raise(rb_eRuntimeError, "Failed to open archive");
27
+ }
28
+ }
29
+
30
+ static VALUE rb_SFileCloseArchive(VALUE self, VALUE handle) {
31
+ HANDLE hMpq = (HANDLE)NUM2ULONG(handle);
32
+
33
+ if (SFileCloseArchive(hMpq)) {
34
+ return Qtrue;
35
+ } else {
36
+ return Qfalse;
37
+ }
38
+ }
39
+
40
+ static VALUE rb_SFileAddFileEx(VALUE self, VALUE handle, VALUE filename, VALUE archived_name, VALUE flags) {
41
+ HANDLE hMpq = (HANDLE)NUM2ULONG(handle);
42
+ const char* szFileName = StringValueCStr(filename);
43
+ const char* szArchivedName = StringValueCStr(archived_name);
44
+ DWORD dwFlags = NUM2ULONG(flags);
45
+
46
+ if (SFileAddFileEx(hMpq, szFileName, szArchivedName, dwFlags, MPQ_COMPRESSION_ZLIB, MPQ_COMPRESSION_NEXT_SAME)) {
47
+ return Qtrue;
48
+ } else {
49
+ return Qfalse;
50
+ }
51
+ }
52
+
53
+ static VALUE rb_SFileExtractFile(VALUE self, VALUE handle, VALUE archived_name, VALUE filename) {
54
+ HANDLE hMpq = (HANDLE)NUM2ULONG(handle);
55
+ const char* szArchivedName = StringValueCStr(archived_name);
56
+ const char* szFileName = StringValueCStr(filename);
57
+
58
+ if (SFileExtractFile(hMpq, szArchivedName, szFileName, SFILE_OPEN_FROM_MPQ)) {
59
+ return Qtrue;
60
+ } else {
61
+ return Qfalse;
62
+ }
63
+ }
64
+
65
+ static VALUE rb_SFileListFiles(VALUE self, VALUE handle) {
66
+ HANDLE hMpq = (HANDLE)NUM2ULONG(handle);
67
+ SFILE_FIND_DATA findFileData;
68
+ HANDLE hFind;
69
+ VALUE fileList = rb_ary_new();
70
+
71
+ hFind = SFileFindFirstFile(hMpq, "*", &findFileData, NULL);
72
+ if (hFind != NULL) {
73
+ do {
74
+ rb_ary_push(fileList, rb_str_new_cstr(findFileData.cFileName));
75
+ } while (SFileFindNextFile(hFind, &findFileData));
76
+
77
+ SFileFindClose(hFind);
78
+ }
79
+
80
+ return fileList;
81
+ }
82
+
83
+ void Init_stormlib() {
84
+ VALUE mStormLib = rb_define_module("StormLib");
85
+
86
+ rb_define_singleton_method(mStormLib, "create_archive", rb_SFileCreateArchive, 3);
87
+ rb_define_singleton_method(mStormLib, "open_archive", rb_SFileOpenArchive, 3);
88
+ rb_define_singleton_method(mStormLib, "close_archive", rb_SFileCloseArchive, 1);
89
+ rb_define_singleton_method(mStormLib, "add_file", rb_SFileAddFileEx, 4);
90
+ rb_define_singleton_method(mStormLib, "extract_file", rb_SFileExtractFile, 3);
91
+ rb_define_singleton_method(mStormLib, "list_files", rb_SFileListFiles, 1);
92
+ }
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Stormlib
4
+ VERSION = '0.1.0'
5
+ end
data/lib/stormlib.rb ADDED
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'stormlib/version'
4
+ require_relative 'stormlib/stormlib'
5
+
6
+ module StormLib
7
+ class Archive
8
+ def initialize(filename, create: false, max_file_count: 1000)
9
+ if create
10
+ @handle = StormLib.create_archive(filename, 0, max_file_count)
11
+ else
12
+ @handle = StormLib.open_archive(filename, 0, 0)
13
+ end
14
+ end
15
+
16
+ def close
17
+ StormLib.close_archive(@handle)
18
+ end
19
+
20
+ def add_file(filename, archived_name, flags = 0)
21
+ StormLib.add_file(@handle, filename, archived_name, flags)
22
+ end
23
+
24
+ def extract_file(archived_name, filename)
25
+ StormLib.extract_file(@handle, archived_name, filename)
26
+ end
27
+
28
+ def list_files
29
+ StormLib.list_files(@handle)
30
+ end
31
+ end
32
+ end
data/stormlib.gemspec ADDED
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/stormlib/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'stormlib'
7
+ spec.version = Stormlib::VERSION
8
+ spec.authors = ['sebi']
9
+ spec.email = ['gore.sebyx@yahoo.com']
10
+
11
+ spec.summary = 'MPQ library for Ruby using the StormLib C library'
12
+ spec.description = 'MPQ library for Ruby using the StormLib C library'
13
+ spec.homepage = 'https://github.com/sebyx07/stormlib'
14
+ spec.license = 'MIT'
15
+ spec.required_ruby_version = '>= 3.0.0'
16
+
17
+ spec.metadata['allowed_push_host'] = 'https://rubygems.org'
18
+ spec.extensions = ['ext/stormlib/extconf.rb']
19
+
20
+ spec.metadata['homepage_uri'] = spec.homepage
21
+ spec.metadata['source_code_uri'] = spec.homepage
22
+
23
+ gemspec = File.basename(__FILE__)
24
+ spec.files = Dir.glob('{lib,ext}/**/*') + %w[README.md LICENSE.txt CHANGELOG.md] + [gemspec]
25
+ spec.files = spec.files.reject do |f|
26
+ f.end_with?('.o', '.so') || f.include?('ext/stormlib/StormLib')
27
+ end
28
+
29
+ spec.bindir = 'exe'
30
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
31
+ spec.require_paths = ['lib']
32
+
33
+ spec.add_development_dependency 'rake-compiler', '>= 1.2.7'
34
+ spec.add_development_dependency 'rake', '>= 13'
35
+ end
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: stormlib
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - sebi
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2024-09-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rake-compiler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.2.7
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 1.2.7
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '13'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '13'
41
+ description: MPQ library for Ruby using the StormLib C library
42
+ email:
43
+ - gore.sebyx@yahoo.com
44
+ executables: []
45
+ extensions:
46
+ - ext/stormlib/extconf.rb
47
+ extra_rdoc_files: []
48
+ files:
49
+ - CHANGELOG.md
50
+ - LICENSE.txt
51
+ - README.md
52
+ - ext/stormlib/extconf.rb
53
+ - ext/stormlib/stormlib.c
54
+ - lib/stormlib.rb
55
+ - lib/stormlib/version.rb
56
+ - stormlib.gemspec
57
+ homepage: https://github.com/sebyx07/stormlib
58
+ licenses:
59
+ - MIT
60
+ metadata:
61
+ allowed_push_host: https://rubygems.org
62
+ homepage_uri: https://github.com/sebyx07/stormlib
63
+ source_code_uri: https://github.com/sebyx07/stormlib
64
+ post_install_message:
65
+ rdoc_options: []
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: 3.0.0
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ requirements: []
79
+ rubygems_version: 3.5.17
80
+ signing_key:
81
+ specification_version: 4
82
+ summary: MPQ library for Ruby using the StormLib C library
83
+ test_files: []