Client Upload Part 2

RD Core / Commit #5

Commit Client Upload Part 2

Alex Alex committed 19/10/2026 00:06 main Patch
1,244 files +271,215 -0
A RD_Client/src/framework/sound/soundchannel.h +69-0 View file
@@ -0,0 +1,69 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifdef FW_SOUND
24+
25+#ifndef SHOUNDCHANNEL_H
26+#define SHOUNDCHANNEL_H
27+
28+#include "soundsource.h"
29+
30+// @bindclass
31+class SoundChannel : public LuaObject
32+{
33+public:
34+ SoundChannel(int id) : m_id(id), m_gain(1) { }
35+
36+ SoundSourcePtr play(const std::string& filename, float fadetime = 0, float gain = 1.0f);
37+ void stop(float fadetime = 0);
38+ void enqueue(const std::string& filename, float fadetime = 0, float gain = 1.0f);
39+ void enable() { setEnabled(true); }
40+ void disable() { setEnabled(false); }
41+
42+ void setGain(float gain);
43+ float getGain() { return m_gain; }
44+
45+ void setEnabled(bool enable);
46+ bool isEnabled() { return m_enabled; }
47+
48+ int getId() { return m_id; }
49+
50+protected:
51+ void update();
52+ friend class SoundManager;
53+
54+private:
55+ struct QueueEntry {
56+ std::string filename;
57+ float fadetime;
58+ float gain;
59+ };
60+ std::deque<QueueEntry> m_queue;
61+ SoundSourcePtr m_currentSource;
62+ stdext::boolean<true> m_enabled;
63+ int m_id;
64+ float m_gain;
65+};
66+
67+#endif
68+
69+#endif
A RD_Client/src/framework/sound/soundfile.cpp +72-0 View file
@@ -0,0 +1,72 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifdef FW_SOUND
24+
25+#include "soundfile.h"
26+#include "oggsoundfile.h"
27+#include <framework/core/resourcemanager.h>
28+
29+SoundFile::SoundFile(const FileStreamPtr& fileStream)
30+{
31+ m_file = fileStream;
32+}
33+
34+SoundFilePtr SoundFile::loadSoundFile(const std::string& filename)
35+{
36+ stdext::timer t;
37+ FileStreamPtr file = g_resources.openFile(filename);
38+ if(!file)
39+ stdext::throw_exception(stdext::format("unable to open %s", filename));
40+
41+ char magic[4];
42+ file->read(magic, 4);
43+ file->seek(0);
44+
45+ SoundFilePtr soundFile;
46+ if(strncmp(magic, "OggS", 4) == 0) {
47+ OggSoundFilePtr oggSoundFile = OggSoundFilePtr(new OggSoundFile(file));
48+ if(oggSoundFile->prepareOgg())
49+ soundFile = oggSoundFile;
50+ } else
51+ stdext::throw_exception(stdext::format("unknown sound file format %s", filename));
52+
53+ return soundFile;
54+}
55+
56+ALenum SoundFile::getSampleFormat()
57+{
58+ if(m_channels == 2) {
59+ if(m_bps == 16)
60+ return AL_FORMAT_STEREO16;
61+ else if(m_bps == 8)
62+ return AL_FORMAT_STEREO8;
63+ } else if(m_channels == 1) {
64+ if(m_bps == 16)
65+ return AL_FORMAT_MONO16;
66+ else if(m_bps == 8)
67+ return AL_FORMAT_MONO8;
68+ }
69+ return AL_UNDETERMINED;
70+}
71+
72+#endif
A RD_Client/src/framework/sound/soundfile.h +60-0 View file
@@ -0,0 +1,60 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifdef FW_SOUND
24+
25+#ifndef SOUNDFILE_H
26+#define SOUNDFILE_H
27+
28+#include "declarations.h"
29+#include <framework/core/filestream.h>
30+
31+class SoundFile : public stdext::shared_object
32+{
33+public:
34+ SoundFile(const FileStreamPtr& fileStream);
35+ virtual ~SoundFile() { }
36+ static SoundFilePtr loadSoundFile(const std::string& filename);
37+
38+ virtual int read(void *buffer, int bufferSize) { return -1; }
39+ virtual void reset() { }
40+ bool eof() { return m_file->eof(); }
41+
42+ ALenum getSampleFormat();
43+
44+ int getChannels() { return m_channels; }
45+ int getRate() { return m_rate; }
46+ int getBps() { return m_bps; }
47+ int getSize() { return m_size; }
48+ std::string getName() { return m_file ? m_file->name() : std::string(); }
49+
50+protected:
51+ FileStreamPtr m_file;
52+ int m_channels;
53+ int m_rate;
54+ int m_bps;
55+ int m_size;
56+};
57+
58+#endif
59+
60+#endif
A RD_Client/src/framework/sound/soundmanager.cpp +303-0 View file
@@ -0,0 +1,303 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifdef FW_SOUND
24+
25+#include "soundmanager.h"
26+#include "soundsource.h"
27+#include "soundbuffer.h"
28+#include "soundfile.h"
29+#include "streamsoundsource.h"
30+#include "combinedsoundsource.h"
31+
32+#include <framework/core/clock.h>
33+#include <framework/core/eventdispatcher.h>
34+#include <framework/core/resourcemanager.h>
35+#include <framework/core/asyncdispatcher.h>
36+#include <thread>
37+#include <framework/util/stats.h>
38+
39+SoundManager g_sounds;
40+
41+void SoundManager::init()
42+{
43+ m_device = alcOpenDevice(NULL);
44+ if(!m_device) {
45+ g_logger.error("unable to open audio device");
46+ return;
47+ }
48+
49+ m_context = alcCreateContext(m_device, NULL);
50+ if(!m_context) {
51+ g_logger.error(stdext::format("unable to create audio context: %s", alcGetString(m_device, alcGetError(m_device))));
52+ return;
53+ }
54+
55+ if(alcMakeContextCurrent(m_context) != ALC_TRUE) {
56+ g_logger.error(stdext::format("unable to make context current: %s", alcGetString(m_device, alcGetError(m_device))));
57+ return;
58+ }
59+}
60+
61+void SoundManager::terminate()
62+{
63+ ensureContext();
64+
65+ for(auto it = m_streamFiles.begin(); it != m_streamFiles.end();++it) {
66+ auto& future = it->second;
67+ future.wait();
68+ }
69+ m_streamFiles.clear();
70+
71+ m_sources.clear();
72+ m_buffers.clear();
73+ m_channels.clear();
74+
75+ m_audioEnabled = false;
76+
77+ alcMakeContextCurrent(nullptr);
78+
79+ if(m_context) {
80+ alcDestroyContext(m_context);
81+ m_context = nullptr;
82+ }
83+
84+ if(m_device) {
85+ alcCloseDevice(m_device);
86+ m_device = nullptr;
87+ }
88+}
89+
90+void SoundManager::poll()
91+{
92+ AutoStat s(STATS_MAIN, "PollSounds");
93+
94+ static ticks_t lastUpdate = 0;
95+ ticks_t now = g_clock.millis();
96+
97+ if(now - lastUpdate < POLL_DELAY)
98+ return;
99+
100+ lastUpdate = now;
101+
102+ ensureContext();
103+
104+ for(auto it = m_streamFiles.begin(); it != m_streamFiles.end();) {
105+ StreamSoundSourcePtr source = it->first;
106+ auto& future = it->second;
107+
108+ if(future.valid()) {
109+ SoundFilePtr sound = future.get();
110+ if(sound)
111+ source->setSoundFile(sound);
112+ else
113+ source->stop();
114+ it = m_streamFiles.erase(it);
115+ } else {
116+ ++it;
117+ }
118+ }
119+
120+ for(auto it = m_sources.begin(); it != m_sources.end();) {
121+ SoundSourcePtr source = *it;
122+
123+ source->update();
124+
125+ if(!source->isPlaying())
126+ it = m_sources.erase(it);
127+ else
128+ ++it;
129+ }
130+
131+ for(auto it : m_channels) {
132+ it.second->update();
133+ }
134+
135+ if(m_context) {
136+ alcProcessContext(m_context);
137+ }
138+}
139+
140+void SoundManager::setAudioEnabled(bool enable)
141+{
142+ if(m_audioEnabled == enable)
143+ return;
144+
145+ m_audioEnabled = enable;
146+ if(!enable) {
147+ ensureContext();
148+ for(const SoundSourcePtr& source : m_sources) {
149+ source->stop();
150+ }
151+ }
152+}
153+
154+void SoundManager::preload(std::string filename)
155+{
156+ filename = resolveSoundFile(filename);
157+
158+ auto it = m_buffers.find(filename);
159+ if(it != m_buffers.end())
160+ return;
161+
162+ ensureContext();
163+ SoundFilePtr soundFile = SoundFile::loadSoundFile(filename);
164+
165+ // only keep small files
166+ if(!soundFile || soundFile->getSize() > MAX_CACHE_SIZE)
167+ return;
168+
169+ SoundBufferPtr buffer = SoundBufferPtr(new SoundBuffer);
170+ if(buffer->fillBuffer(soundFile))
171+ m_buffers[filename] = buffer;
172+}
173+
174+SoundSourcePtr SoundManager::play(std::string filename, float fadetime, float gain)
175+{
176+ if(!m_audioEnabled)
177+ return nullptr;
178+
179+ ensureContext();
180+
181+ filename = resolveSoundFile(filename);
182+ SoundSourcePtr soundSource = createSoundSource(filename);
183+ if(!soundSource) {
184+ g_logger.error(stdext::format("unable to play '%s'", filename));
185+ return nullptr;
186+ }
187+
188+ soundSource->setName(filename);
189+ soundSource->setRelative(true);
190+ soundSource->setGain(gain);
191+
192+ if(fadetime > 0)
193+ soundSource->setFading(StreamSoundSource::FadingOn, fadetime);
194+
195+ soundSource->play();
196+
197+ m_sources.push_back(soundSource);
198+
199+ return soundSource;
200+}
201+
202+SoundChannelPtr SoundManager::getChannel(int channel)
203+{
204+ ensureContext();
205+ if(!m_channels[channel])
206+ m_channels[channel] = SoundChannelPtr(new SoundChannel(channel));
207+ return m_channels[channel];
208+}
209+
210+void SoundManager::stopAll()
211+{
212+ ensureContext();
213+ for(const SoundSourcePtr& source : m_sources) {
214+ source->stop();
215+ }
216+
217+ for(auto it : m_channels) {
218+ it.second->stop();
219+ }
220+}
221+
222+SoundSourcePtr SoundManager::createSoundSource(const std::string& filename)
223+{
224+ SoundSourcePtr source;
225+
226+ try {
227+ auto it = m_buffers.find(filename);
228+ if(it != m_buffers.end()) {
229+ source = SoundSourcePtr(new SoundSource);
230+ source->setBuffer(it->second);
231+ } else {
232+#if defined __linux && !defined OPENGL_ES
233+ // due to OpenAL implementation bug, stereo buffers are always downmixed to mono on linux systems
234+ // this is hack to work around the issue
235+ // solution taken from http://opensource.creative.com/pipermail/openal/2007-April/010355.html
236+ CombinedSoundSourcePtr combinedSource(new CombinedSoundSource);
237+ StreamSoundSourcePtr streamSource;
238+
239+ streamSource = StreamSoundSourcePtr(new StreamSoundSource);
240+ streamSource->downMix(StreamSoundSource::DownMixLeft);
241+ streamSource->setRelative(true);
242+ streamSource->setPosition(Point(-128, 0));
243+ combinedSource->addSource(streamSource);
244+ m_streamFiles[streamSource] = g_asyncDispatcher.schedule([=]() -> SoundFilePtr {
245+ stdext::timer a;
246+ try {
247+ return SoundFile::loadSoundFile(filename);
248+ } catch(std::exception& e) {
249+ g_logger.error(e.what());
250+ return nullptr;
251+ }
252+ });
253+
254+ streamSource = StreamSoundSourcePtr(new StreamSoundSource);
255+ streamSource->downMix(StreamSoundSource::DownMixRight);
256+ streamSource->setRelative(true);
257+ streamSource->setPosition(Point(128,0));
258+ combinedSource->addSource(streamSource);
259+ m_streamFiles[streamSource] = g_asyncDispatcher.schedule([=]() -> SoundFilePtr {
260+ try {
261+ return SoundFile::loadSoundFile(filename);
262+ } catch(std::exception& e) {
263+ g_logger.error(e.what());
264+ return nullptr;
265+ }
266+ });
267+
268+ source = combinedSource;
269+#else
270+ StreamSoundSourcePtr streamSource(new StreamSoundSource);
271+ m_streamFiles[streamSource] = g_asyncDispatcher.schedule([=]() -> SoundFilePtr {
272+ try {
273+ return SoundFile::loadSoundFile(filename);
274+ } catch(std::exception& e) {
275+ g_logger.error(e.what());
276+ return nullptr;
277+ }
278+ });
279+ source = streamSource;
280+#endif
281+ }
282+ } catch(std::exception& e) {
283+ g_logger.error(stdext::format("failed to load sound source: '%s'", e.what()));
284+ return nullptr;
285+ }
286+
287+ return source;
288+}
289+
290+std::string SoundManager::resolveSoundFile(std::string file)
291+{
292+ file = g_resources.guessFilePath(file, "ogg");
293+ file = g_resources.resolvePath(file);
294+ return file;
295+}
296+
297+void SoundManager::ensureContext()
298+{
299+ if(m_context)
300+ alcMakeContextCurrent(m_context);
301+}
302+
303+#endif
A RD_Client/src/framework/sound/soundmanager.h +73-0 View file
@@ -0,0 +1,73 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifdef FW_SOUND
24+
25+#ifndef SOUNDMANAGER_H
26+#define SOUNDMANAGER_H
27+
28+#include "declarations.h"
29+#include "soundchannel.h"
30+
31+//@bindsingleton g_sounds
32+class SoundManager
33+{
34+ enum {
35+ MAX_CACHE_SIZE = 100000,
36+ POLL_DELAY = 100
37+ };
38+public:
39+ void init();
40+ void terminate();
41+ void poll();
42+
43+ void setAudioEnabled(bool enable);
44+ bool isAudioEnabled() { return m_device && m_context && m_audioEnabled ; }
45+ void enableAudio() { setAudioEnabled(true); }
46+ void disableAudio() { setAudioEnabled(true); }
47+ void stopAll();
48+
49+ void preload(std::string filename);
50+ SoundSourcePtr play(std::string filename, float fadetime = 0, float gain = 0);
51+ SoundChannelPtr getChannel(int channel);
52+
53+ std::string resolveSoundFile(std::string file);
54+ void ensureContext();
55+
56+private:
57+ SoundSourcePtr createSoundSource(const std::string& filename);
58+
59+ ALCdevice *m_device;
60+ ALCcontext *m_context;
61+
62+ std::map<StreamSoundSourcePtr, std::shared_future<SoundFilePtr>> m_streamFiles;
63+ std::unordered_map<std::string, SoundBufferPtr> m_buffers;
64+ std::vector<SoundSourcePtr> m_sources;
65+ stdext::boolean<true> m_audioEnabled;
66+ std::unordered_map<int, SoundChannelPtr> m_channels;
67+};
68+
69+extern SoundManager g_sounds;
70+
71+#endif
72+
73+#endif
A RD_Client/src/framework/sound/soundsource.cpp +165-0 View file
@@ -0,0 +1,165 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifdef FW_SOUND
24+
25+#include "soundsource.h"
26+#include "soundbuffer.h"
27+
28+#include <framework/core/clock.h>
29+
30+SoundSource::SoundSource()
31+{
32+ m_sourceId = 0;
33+ m_channel = 0;
34+ m_fadeState = NoFading;
35+ m_fadeTime = 0;
36+ m_fadeStartTime = 0;
37+ m_fadeGain = 0;
38+ m_gain = 1.0f;
39+
40+ alGenSources(1, &m_sourceId);
41+ VALIDATE(alGetError() == AL_NO_ERROR);
42+ setReferenceDistance(128);
43+}
44+
45+SoundSource::~SoundSource()
46+{
47+ if(m_sourceId != 0) {
48+ stop();
49+ alDeleteSources(1, &m_sourceId);
50+ VALIDATE(alGetError() == AL_NO_ERROR);
51+ }
52+}
53+
54+void SoundSource::play()
55+{
56+ alSourcePlay(m_sourceId);
57+ VALIDATE(alGetError() == AL_NO_ERROR);
58+}
59+
60+void SoundSource::stop()
61+{
62+ alSourceStop(m_sourceId);
63+ VALIDATE(alGetError() == AL_NO_ERROR);
64+ if(m_buffer) {
65+ alSourcei(m_sourceId, AL_BUFFER, AL_NONE);
66+ VALIDATE(alGetError() == AL_NO_ERROR);
67+ m_buffer = nullptr;
68+ }
69+}
70+
71+bool SoundSource::isBuffering()
72+{
73+ int state = AL_PLAYING;
74+ alGetSourcei(m_sourceId, AL_SOURCE_STATE, &state);
75+ return state != AL_STOPPED;
76+}
77+
78+void SoundSource::setBuffer(const SoundBufferPtr& buffer)
79+{
80+ alSourcei(m_sourceId, AL_BUFFER, buffer->getBufferId());
81+ VALIDATE(alGetError() == AL_NO_ERROR);
82+ m_buffer = buffer;
83+}
84+
85+void SoundSource::setLooping(bool looping)
86+{
87+ alSourcei(m_sourceId, AL_LOOPING, looping ? AL_TRUE : AL_FALSE);
88+}
89+
90+void SoundSource::setRelative(bool relative)
91+{
92+ alSourcei(m_sourceId, AL_SOURCE_RELATIVE, relative ? AL_TRUE : AL_FALSE);
93+}
94+
95+void SoundSource::setReferenceDistance(float distance)
96+{
97+ alSourcef(m_sourceId, AL_REFERENCE_DISTANCE, distance);
98+}
99+
100+void SoundSource::setGain(float gain)
101+{
102+ alSourcef(m_sourceId, AL_GAIN, gain);
103+ m_gain = gain;
104+}
105+
106+void SoundSource::setPitch(float pitch)
107+{
108+ alSourcef(m_sourceId, AL_PITCH, pitch);
109+}
110+
111+void SoundSource::setPosition(const Point& pos)
112+{
113+ alSource3f(m_sourceId, AL_POSITION, pos.x, pos.y, 0);
114+}
115+
116+void SoundSource::setVelocity(const Point& velocity)
117+{
118+ alSource3f(m_sourceId, AL_VELOCITY, velocity.x, velocity.y, 0);
119+}
120+
121+void SoundSource::setFading(FadeState state, float fadeTime)
122+{
123+ float now = stdext::millis() / 1000.0f;
124+ if(m_fadeState != NoFading) {
125+ float elapsed = now - m_fadeStartTime;
126+ float add;
127+ if(m_fadeState == FadingOn)
128+ add = -(1-(elapsed / m_fadeTime))*fadeTime;
129+ else
130+ add = -(elapsed / m_fadeTime)*fadeTime;
131+ m_fadeStartTime = now + add;
132+ } else
133+ m_fadeStartTime = now;
134+
135+ m_fadeState = state;
136+ m_fadeTime = fadeTime;
137+ m_fadeGain = m_gain;
138+
139+ if(m_fadeState == FadingOn)
140+ setGain(0.0);
141+}
142+
143+void SoundSource::update()
144+{
145+ float now = stdext::millis() / 1000.0f;
146+ if(m_fadeState == FadingOn) {
147+ float elapsed = now - m_fadeStartTime;
148+ if(elapsed >= m_fadeTime) {
149+ m_fadeState = NoFading;
150+ } else {
151+ setGain((elapsed / m_fadeTime) * m_fadeGain);
152+ }
153+ } else if(m_fadeState == FadingOff) {
154+ float elapsed = now - m_fadeStartTime;
155+ if(elapsed >= m_fadeTime) {
156+ setGain(m_fadeGain);
157+ stop();
158+ m_fadeState = NoFading;
159+ } else {
160+ setGain(((m_fadeTime - elapsed) / m_fadeTime) * m_fadeGain);
161+ }
162+ }
163+}
164+
165+#endif
A RD_Client/src/framework/sound/soundsource.h +84-0 View file
@@ -0,0 +1,84 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifdef FW_SOUND
24+
25+#ifndef SOUNDSOURCE_H
26+#define SOUNDSOURCE_H
27+
28+#include "declarations.h"
29+#include "soundbuffer.h"
30+#include <framework/luaengine/luaobject.h>
31+
32+class SoundSource : public LuaObject
33+{
34+protected:
35+ SoundSource(uint sourceId) : m_sourceId(sourceId) { }
36+
37+public:
38+ enum FadeState { NoFading, FadingOn, FadingOff };
39+
40+ SoundSource();
41+ virtual ~SoundSource();
42+
43+ virtual void play();
44+ virtual void stop();
45+
46+ virtual bool isBuffering();
47+ virtual bool isPlaying() { return isBuffering(); }
48+
49+ void setName(const std::string& name) { m_name = name; }
50+ virtual void setLooping(bool looping);
51+ virtual void setRelative(bool relative);
52+ virtual void setReferenceDistance(float distance);
53+ virtual void setGain(float gain);
54+ virtual void setPitch(float pitch);
55+ virtual void setPosition(const Point& pos);
56+ virtual void setVelocity(const Point& velocity);
57+ virtual void setFading(FadeState state, float fadetime);
58+
59+ std::string getName() { return m_name; }
60+ uchar getChannel() { return m_channel; }
61+ float getGain() { return m_gain; }
62+
63+protected:
64+ void setBuffer(const SoundBufferPtr& buffer);
65+ void setChannel(uchar channel) { m_channel = channel; }
66+
67+ virtual void update();
68+ friend class SoundManager;
69+ friend class CombinedSoundSource;
70+
71+ uint m_sourceId;
72+ uchar m_channel;
73+ std::string m_name;
74+ SoundBufferPtr m_buffer;
75+ FadeState m_fadeState;
76+ float m_fadeStartTime;
77+ float m_fadeTime;
78+ float m_fadeGain;
79+ float m_gain;
80+};
81+
82+#endif
83+
84+#endif
A RD_Client/src/framework/sound/streamsoundsource.cpp +193-0 View file
@@ -0,0 +1,193 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifdef FW_SOUND
24+
25+#include "streamsoundsource.h"
26+#include "soundbuffer.h"
27+#include "soundfile.h"
28+
29+#include <framework/util/databuffer.h>
30+#include <boost/concept_check.hpp>
31+
32+StreamSoundSource::StreamSoundSource()
33+{
34+ for(auto& buffer : m_buffers)
35+ buffer = SoundBufferPtr(new SoundBuffer);
36+ m_downMix = NoDownMix;
37+}
38+
39+StreamSoundSource::~StreamSoundSource()
40+{
41+ stop();
42+}
43+
44+void StreamSoundSource::setSoundFile(const SoundFilePtr& soundFile)
45+{
46+ m_soundFile = soundFile;
47+ if(m_waitingFile) {
48+ m_waitingFile = false;
49+ play();
50+ }
51+}
52+
53+void StreamSoundSource::play()
54+{
55+ m_playing = true;
56+
57+ if(!m_soundFile) {
58+ m_waitingFile = true;
59+ return;
60+ }
61+
62+ if(m_eof) {
63+ m_soundFile->reset();
64+ m_eof = false;
65+ }
66+
67+ queueBuffers();
68+
69+ SoundSource::play();
70+}
71+
72+void StreamSoundSource::stop()
73+{
74+ m_playing = false;
75+
76+ if(m_waitingFile)
77+ return;
78+
79+ SoundSource::stop();
80+ unqueueBuffers();
81+}
82+
83+void StreamSoundSource::queueBuffers()
84+{
85+ int queued;
86+ alGetSourcei(m_sourceId, AL_BUFFERS_QUEUED, &queued);
87+ for(int i = 0; i < STREAM_FRAGMENTS - queued; ++i) {
88+ if(!fillBufferAndQueue(m_buffers[i]->getBufferId()))
89+ break;
90+ }
91+}
92+
93+void StreamSoundSource::unqueueBuffers()
94+{
95+ int queued;
96+ alGetSourcei(m_sourceId, AL_BUFFERS_QUEUED, &queued);
97+ for(int i = 0; i < queued; ++i) {
98+ uint buffer;
99+ alSourceUnqueueBuffers(m_sourceId, 1, &buffer);
100+ }
101+}
102+
103+void StreamSoundSource::update()
104+{
105+ if(m_waitingFile)
106+ return;
107+
108+ SoundSource::update();
109+
110+ int processed = 0;
111+ alGetSourcei(m_sourceId, AL_BUFFERS_PROCESSED, &processed);
112+ for(int i = 0; i < processed; ++i) {
113+ uint buffer;
114+ alSourceUnqueueBuffers(m_sourceId, 1, &buffer);
115+ //SoundManager::check_al_error("Couldn't unqueue audio buffer: ");
116+
117+ if(!fillBufferAndQueue(buffer))
118+ break;
119+ }
120+
121+ if(!isBuffering() && m_playing) {
122+ if(!m_looping && m_eof) {
123+ stop();
124+ } else if(processed == 0) {
125+ g_logger.traceError("audio buffer underrun");
126+ play();
127+ } else if(m_looping) {
128+ play();
129+ }
130+ }
131+}
132+
133+bool StreamSoundSource::fillBufferAndQueue(uint buffer)
134+{
135+ if(m_waitingFile)
136+ return false;
137+
138+ // fill buffer
139+ static DataBuffer<char> bufferData(2*STREAM_FRAGMENT_SIZE);
140+ ALenum format = m_soundFile->getSampleFormat();
141+
142+ int maxRead = STREAM_FRAGMENT_SIZE;
143+ if(m_downMix != NoDownMix)
144+ maxRead *= 2;
145+
146+ int bytesRead = 0;
147+ do {
148+ bytesRead += m_soundFile->read(&bufferData[bytesRead], maxRead - bytesRead);
149+
150+ // end of sound file
151+ if(bytesRead < maxRead) {
152+ if(m_looping)
153+ m_soundFile->reset();
154+ else {
155+ m_eof = true;
156+ break;
157+ }
158+ }
159+ } while(bytesRead < maxRead);
160+
161+ if(bytesRead > 0) {
162+ if(m_downMix != NoDownMix) {
163+ if(format == AL_FORMAT_STEREO16) {
164+ VALIDATE(bytesRead % 2 == 0);
165+ bytesRead /= 2;
166+ uint16_t *data = (uint16_t*)bufferData.data();
167+ for(int i=0;i<bytesRead/2;i++)
168+ data[i] = data[2*i + (m_downMix == DownMixLeft ? 0 : 1)];
169+ format = AL_FORMAT_MONO16;
170+ }
171+ }
172+
173+ alBufferData(buffer, format, &bufferData[0], bytesRead, m_soundFile->getRate());
174+ ALenum err = alGetError();
175+ if(err != AL_NO_ERROR)
176+ g_logger.error(stdext::format("unable to refill audio buffer for '%s': %s", m_soundFile->getName(), alGetString(err)));
177+
178+ alSourceQueueBuffers(m_sourceId, 1, &buffer);
179+ err = alGetError();
180+ if(err != AL_NO_ERROR)
181+ g_logger.error(stdext::format("unable to queue audio buffer for '%s': %s", m_soundFile->getName(), alGetString(err)));
182+ }
183+
184+ // return false if there aren't more buffers to fill
185+ return (bytesRead >= STREAM_FRAGMENT_SIZE && !m_eof);
186+}
187+
188+void StreamSoundSource::downMix(StreamSoundSource::DownMix downMix)
189+{
190+ m_downMix = downMix;
191+}
192+
193+#endif
A RD_Client/src/framework/sound/streamsoundsource.h +71-0 View file
@@ -0,0 +1,71 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifdef FW_SOUND
24+
25+#ifndef STREAMSOUNDSOURCE_H
26+#define STREAMSOUNDSOURCE_H
27+
28+#include "soundsource.h"
29+
30+class StreamSoundSource : public SoundSource
31+{
32+ enum {
33+ STREAM_BUFFER_SIZE = 1024 * 400,
34+ STREAM_FRAGMENTS = 4,
35+ STREAM_FRAGMENT_SIZE = STREAM_BUFFER_SIZE / STREAM_FRAGMENTS
36+ };
37+
38+public:
39+ enum DownMix { NoDownMix, DownMixLeft, DownMixRight };
40+
41+ StreamSoundSource();
42+ virtual ~StreamSoundSource();
43+
44+ void play();
45+ void stop();
46+
47+ bool isPlaying() { return m_playing; }
48+
49+ void setSoundFile(const SoundFilePtr& soundFile);
50+
51+ void downMix(DownMix downMix);
52+
53+ void update();
54+
55+private:
56+ void queueBuffers();
57+ void unqueueBuffers();
58+ bool fillBufferAndQueue(uint buffer);
59+
60+ SoundFilePtr m_soundFile;
61+ std::array<SoundBufferPtr,STREAM_FRAGMENTS> m_buffers;
62+ DownMix m_downMix;
63+ stdext::boolean<false> m_looping;
64+ stdext::boolean<false> m_playing;
65+ stdext::boolean<false> m_eof;
66+ stdext::boolean<false> m_waitingFile;
67+};
68+
69+#endif
70+
71+#endif
A RD_Client/src/framework/stdext/any.h +76-0 View file
@@ -0,0 +1,76 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifndef STDEXT_ANY_H
24+#define STDEXT_ANY_H
25+
26+#include <algorithm>
27+#include <typeinfo>
28+
29+namespace stdext {
30+
31+class any {
32+public:
33+ struct placeholder {
34+ virtual ~placeholder() { }
35+ virtual const std::type_info& type() const = 0;
36+ virtual placeholder* clone() const = 0;
37+ };
38+
39+ template<typename T>
40+ struct holder : public placeholder {
41+ holder(const T& value) : held(value) { }
42+ const std::type_info& type() const { return typeid(T); }
43+ placeholder* clone() const { return new holder(held); }
44+ T held;
45+ private:
46+ holder& operator=(const holder &);
47+ };
48+
49+ placeholder* content;
50+
51+ any() : content(nullptr) { }
52+ any(const any& other) : content(other.content ? other.content->clone() : nullptr) { }
53+ template<typename T> any(const T& value) : content(new holder<T>(value)) { }
54+ ~any() { if(content) delete content; }
55+
56+ any& swap(any& rhs) { std::swap(content, rhs.content); return *this; }
57+
58+ template<typename T> any& operator=(const T& rhs) { any(rhs).swap(*this); return *this; }
59+ any& operator=(any rhs) { rhs.swap(*this); return *this; }
60+
61+ bool empty() const { return !content; }
62+ template<typename T> const T& cast() const;
63+ const std::type_info & type() const { return content ? content->type() : typeid(void); }
64+};
65+
66+template<typename T>
67+const T& any_cast(const any& operand) {
68+ VALIDATE(operand.type() == typeid(T));
69+ return static_cast<any::holder<T>*>(operand.content)->held;
70+}
71+
72+template<typename T> const T& any::cast() const { return any_cast<T>(*this); }
73+
74+}
75+
76+#endif
A RD_Client/src/framework/stdext/boolean.h +40-0 View file
@@ -0,0 +1,40 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifndef BOOLEAN_H
24+#define BOOLEAN_H
25+
26+namespace stdext {
27+
28+template<bool def>
29+struct boolean {
30+ boolean() : v(def) { }
31+ operator bool &() { return v; }
32+ operator bool const &() const { return v; }
33+ bool& operator=(const bool& o) { v = o; return v; }
34+private:
35+ bool v;
36+};
37+
38+}
39+
40+#endif
A RD_Client/src/framework/stdext/cast.h +177-0 View file
@@ -0,0 +1,177 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifndef STDEXT_CAST_H
24+#define STDEXT_CAST_H
25+
26+#include "exception.h"
27+#include "demangle.h"
28+
29+#include <sstream>
30+#include <iostream>
31+#include <cstdlib>
32+
33+namespace stdext {
34+
35+// cast a type to another type
36+template<typename T, typename R>
37+bool cast(const T& in, R& out) {
38+ std::stringstream ss;
39+ ss << in;
40+ ss >> out;
41+ return !!ss && ss.eof();
42+}
43+
44+// cast a type to string
45+template<typename T>
46+bool cast(const T& in, std::string& out) {
47+ std::stringstream ss;
48+ ss << in;
49+ out = ss.str();
50+ return true;
51+}
52+
53+// cast string to string
54+template<>
55+inline bool cast(const std::string& in, std::string& out) {
56+ out = in;
57+ return true;
58+}
59+
60+// special cast from string to boolean
61+template<>
62+inline bool cast(const std::string& in, bool& b) {
63+ if(in == "true")
64+ b = true;
65+ else if(in == "false")
66+ b = false;
67+ else
68+ return false;
69+ return true;
70+}
71+
72+// special cast from string to char
73+template<>
74+inline bool cast(const std::string& in, char& c) {
75+ if(in.length() != 1)
76+ return false;
77+ c = in[0];
78+ return true;
79+}
80+
81+// special cast from string to long
82+template<>
83+inline bool cast(const std::string& in, long& l) {
84+ if(in.find_first_not_of("-0123456789") != std::string::npos)
85+ return false;
86+ std::size_t t = in.find_last_of('-');
87+ if(t != std::string::npos && t != 0)
88+ return false;
89+ l = atol(in.c_str());
90+ return true;
91+}
92+
93+// special cast from string to int
94+template<>
95+inline bool cast(const std::string& in, int& i) {
96+ long l;
97+ if(cast(in, l)) {
98+ i=l;
99+ return true;
100+ }
101+ return false;
102+}
103+
104+// special cast from string to double
105+template<>
106+inline bool cast(const std::string& in, double& d) {
107+ if(in.find_first_not_of("-0123456789.") != std::string::npos)
108+ return false;
109+ std::size_t t = in.find_last_of('-');
110+ if(t != std::string::npos && t != 0)
111+ return false;
112+ t = in.find_first_of('.');
113+ if(t != std::string::npos && (t == 0 || t == in.length()-1 || in.find_first_of('.', t+1) != std::string::npos))
114+ return false;
115+ d = atof(in.c_str());
116+ return true;
117+}
118+
119+// special cast from string to float
120+template<>
121+inline bool cast(const std::string& in, float& f) {
122+ double d;
123+ if(cast(in, d)) {
124+ f=(float)d;
125+ return true;
126+ }
127+ return false;
128+}
129+
130+// special cast from boolean to string
131+template<>
132+inline bool cast(const bool& in, std::string& out) {
133+ out = (in ? "true" : "false");
134+ return true;
135+}
136+
137+// used by safe_cast
138+class cast_exception : public exception {
139+public:
140+ virtual ~cast_exception() throw() { }
141+ template<class T, class R>
142+ void update_what() {
143+ std::stringstream ss;
144+ ss << "failed to cast value of type '" << demangle_type<T>() << "' to type '" << demangle_type<R>() << "'";
145+ m_what = ss.str();
146+ }
147+ virtual const char* what() const throw() { return m_what.c_str(); }
148+private:
149+ std::string m_what;
150+};
151+
152+// cast a type to another type, any error throws a cast_exception
153+template<typename R, typename T>
154+R safe_cast(const T& t) {
155+ R r;
156+ if(!cast(t, r)) {
157+ cast_exception e;
158+ e.update_what<T,R>();
159+ throw e;
160+ }
161+ return r;
162+}
163+
164+// cast a type to another type, cast errors are ignored
165+template<typename R, typename T>
166+R unsafe_cast(const T& t, R def = R()) {
167+ try {
168+ return safe_cast<R,T>(t);
169+ } catch(cast_exception& e) {
170+ std::cerr << "CAST ERROR: " << e.what() << std::endl;
171+ return def;
172+ }
173+}
174+
175+}
176+
177+#endif
A RD_Client/src/framework/stdext/compiler.h +79-0 View file
@@ -0,0 +1,79 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifndef STDEXT_COMPILER_H
24+#define STDEXT_COMPILER_H
25+
26+#ifdef WIN32
27+#include <winsock2.h>
28+#endif
29+
30+#ifdef __clang__
31+ // clang is supported
32+ #define BUILD_COMPILER "clang " __VERSION__
33+#elif defined(__GNUC__)
34+ #if !(__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6))
35+ #error "Sorry, you need gcc 4.6 or greater to compile."
36+ #endif
37+ #define BUILD_COMPILER "gcc " __VERSION__
38+#elif defined(_MSC_VER)
39+ #if _MSC_VER < 1800
40+ #error "You need Visual Studio 2013 or greater to compile."
41+ #endif
42+ #pragma warning(disable:4244) // conversion from 'A' to 'B', possible loss of data
43+ #pragma warning(disable:4267) // '?' : conversion from 'A' to 'B', possible loss of data
44+ #pragma warning(disable:4305) // 'initializing' : truncation from 'A' to 'B'
45+ #pragma warning(disable:4146) // unary minus operator applied to unsigned type, result still unsigned
46+ #pragma warning(disable:4800) // 'A' : forcing value to bool 'true' or 'false' (performance warning)
47+ #pragma warning(disable:4996) // depracated warning as error
48+
49+ #if _MSC_VER == 1912 || _MSC_VER == 1911 || _MSC_VER == 1910
50+ #define BUILD_COMPILER "Visual Studio 2017"
51+ #elif _MSC_VER == 1900
52+ #define BUILD_COMPILER "Visual Studio 2015"
53+ #elif _MSC_VER == 1800
54+ #define BUILD_COMPILER "Visual Studio 2013"
55+ #else
56+ #define BUILD_COMPILER "Visual Studio"
57+ #endif
58+
59+ #define __PRETTY_FUNCTION__ __FUNCDNAME__
60+#else
61+ #error "Compiler not supported."
62+#endif
63+
64+/// Branch Prediction. See the GCC Manual for more information.
65+/// NB: These are used when speed is need most; do not use in normal
66+/// code, they may slow down stuff.
67+#if defined(__clang__) || defined(__GNUC__)
68+#define likely(x) __builtin_expect(!!(x), 1)
69+#define unlikely(x) __builtin_expect(!!(x), 0)
70+#else
71+#define likely(x) (x)
72+#define unlikely(x) (x)
73+#endif
74+
75+#if !defined(_MSC_VER) && !defined(__GXX_EXPERIMENTAL_CXX0X__)
76+#error "C++0x is required to compile this application. Try updating your compiler."
77+#endif
78+
79+#endif
A RD_Client/src/framework/stdext/demangle.cpp +64-0 View file
@@ -0,0 +1,64 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#include "demangle.h"
24+
25+#ifdef _MSC_VER
26+
27+#include <winsock2.h>
28+#include <windows.h>
29+
30+#pragma warning (push)
31+#pragma warning (disable:4091) // warning C4091: 'typedef ': ignored on left of '' when no variable is declared
32+#include <dbghelp.h>
33+#pragma warning (pop)
34+
35+#else
36+
37+#include <cxxabi.h>
38+#include <cstring>
39+#include <cstdlib>
40+
41+#endif
42+
43+namespace stdext {
44+
45+const char* demangle_name(const char* name)
46+{
47+#ifdef _MSC_VER
48+ static char buffer[1024];
49+ UnDecorateSymbolName(name, buffer, sizeof(buffer), UNDNAME_COMPLETE);
50+ return buffer;
51+#else
52+ size_t len;
53+ int status;
54+ static char buffer[1024];
55+ char* demangled = abi::__cxa_demangle(name, 0, &len, &status);
56+ if(demangled) {
57+ strcpy(buffer, demangled);
58+ free(demangled);
59+ }
60+ return buffer;
61+#endif
62+}
63+
64+}
A RD_Client/src/framework/stdext/demangle.h +48-0 View file
@@ -0,0 +1,48 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifndef STDEXT_DEMANGLE_H
24+#define STDEXT_DEMANGLE_H
25+
26+#include <typeinfo>
27+#include <string>
28+
29+namespace stdext {
30+
31+/// Demangle names for GNU g++ compiler
32+const char* demangle_name(const char* name);
33+
34+/// Returns the name of a class
35+template<typename T> std::string demangle_class() {
36+#ifdef _MSC_VER
37+ return demangle_name(typeid(T).name()) + 6;
38+#else
39+ return demangle_name(typeid(T).name());
40+#endif
41+}
42+
43+/// Returns the name of a type
44+template<typename T> std::string demangle_type() { return demangle_name(typeid(T).name()); }
45+
46+}
47+
48+#endif
A RD_Client/src/framework/stdext/dumper.h +42-0 View file
@@ -0,0 +1,42 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifndef STDEXT_DUMPER_H
24+#define STDEXT_DUMPER_H
25+
26+#include <iostream>
27+
28+namespace stdext {
29+
30+static struct {
31+ struct dumper_dummy {
32+ ~dumper_dummy() { std::cout << std::endl; }
33+ template<class T> dumper_dummy& operator<<(const T& v) { std::cout << v << " "; return *this; }
34+ };
35+ template<class T> dumper_dummy operator<<(const T& v) const { dumper_dummy d; d << v; return d; }
36+} dump;
37+
38+}
39+
40+using stdext::dump;
41+
42+#endif
A RD_Client/src/framework/stdext/dynamic_storage.h +67-0 View file
@@ -0,0 +1,67 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifndef STDEXT_DYNAMICSTORAGE_H
24+#define STDEXT_DYNAMICSTORAGE_H
25+
26+#include "types.h"
27+#include "any.h"
28+#include <unordered_map>
29+
30+namespace stdext {
31+
32+template<typename Key>
33+class dynamic_storage {
34+public:
35+ template<typename T> void set(const Key& k, const T& value) {
36+ if(m_data.size() <= k)
37+ m_data.resize(k+1);
38+ m_data[k] = value;
39+ }
40+ bool remove(const Key& k) {
41+ if(m_data.size() < k)
42+ return false;
43+ if(m_data[k].empty())
44+ return false;
45+ m_data[k] = any();
46+ return true;
47+ }
48+ template<typename T> T get(const Key& k) const { return has(k) ? any_cast<T>(m_data[k]) : T(); }
49+ bool has(const Key& k) const { return k < m_data.size() && !m_data[k].empty(); }
50+
51+ std::size_t size() const {
52+ std::size_t count = 0;
53+ for(std::size_t i=0;i<m_data.size();++i)
54+ if(!m_data[i].empty())
55+ count++;
56+ return count;
57+ }
58+
59+ void clear() { m_data.clear(); }
60+
61+private:
62+ std::vector<any> m_data;
63+};
64+
65+}
66+
67+#endif
A RD_Client/src/framework/stdext/exception.h +47-0 View file
@@ -0,0 +1,47 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifndef STDEXT_EXCEPTION_H
24+#define STDEXT_EXCEPTION_H
25+
26+#include <exception>
27+#include <string>
28+
29+namespace stdext {
30+
31+class exception : public std::exception
32+{
33+public:
34+ exception() { }
35+ exception(const std::string& what) : m_what(what) { }
36+ virtual ~exception() throw() { };
37+ virtual const char* what() const throw() { return m_what.c_str(); }
38+protected:
39+ std::string m_what;
40+};
41+
42+/// Throws a generic exception
43+inline void throw_exception(const std::string& what) { throw exception(what); }
44+
45+}
46+
47+#endif
A RD_Client/src/framework/stdext/fastrand.h +12-0 View file
@@ -0,0 +1,12 @@
1+#pragma once
2+
3+namespace stdext {
4+
5+static int fastrand()
6+{
7+ static int g_seed = (214013 + 2531011);
8+ g_seed = (214013 * g_seed + 2531011);
9+ return (g_seed >> 16) & 0x7FFF;
10+};
11+
12+}
A RD_Client/src/framework/stdext/format.h +100-0 View file
@@ -0,0 +1,100 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifndef STDEXT_FORMAT_H
24+#define STDEXT_FORMAT_H
25+
26+#include "traits.h"
27+
28+#include <string>
29+#include <cstdio>
30+#include <tuple>
31+#include <iostream>
32+#include <sstream>
33+#include <iomanip>
34+
35+namespace stdext {
36+
37+template<class T> void print_ostream(std::ostringstream& stream, const T& last) { stream << last; }
38+template<class T, class... Args>
39+void print_ostream(std::ostringstream& stream, const T& first, const Args&... rest) { stream << "\t" << first; print_ostream(stream, rest...); }
40+template<class... T>
41+
42+// Utility for printing variables just like lua
43+void print(const T&... args) { std::ostringstream buf; print_ostream(buf, args...); std::cout << buf.str() << std::endl; }
44+
45+template<typename T>
46+typename std::enable_if<std::is_integral<T>::value ||
47+ std::is_pointer<T>::value ||
48+ std::is_floating_point<T>::value ||
49+ std::is_enum<T>::value, T>::type sprintf_cast(const T& t) { return t; }
50+inline const char *sprintf_cast(const char *s) { return s; }
51+inline const char *sprintf_cast(const std::string& s) { return s.c_str(); }
52+
53+template<int N> struct expand_snprintf {
54+ template<typename Tuple, typename... Args> static int call(char *s, size_t maxlen, const char *format, const Tuple& tuple, const Args&... args) {
55+ return expand_snprintf<N-1>::call(s, maxlen, format, tuple, sprintf_cast(std::get<N-1>(tuple)), args...); }};
56+template<> struct expand_snprintf<0> {
57+ template<typename Tuple, typename... Args> static int call(char *s, size_t maxlen, const char *format, const Tuple& tuple, const Args&... args) {
58+#ifdef _MSC_VER
59+ return _snprintf(s, maxlen, format, args...);
60+#else
61+ return snprintf(s, maxlen, format, args...);
62+#endif
63+ }
64+};
65+
66+// Improved snprintf that accepts std::string and other types
67+template<typename... Args>
68+int snprintf(char *s, size_t maxlen, const char *format, const Args&... args) {
69+ std::tuple<typename replace_extent<Args>::type...> tuple(args...);
70+ return expand_snprintf<std::tuple_size<decltype(tuple)>::value>::call(s, maxlen, format, tuple);
71+}
72+
73+template<typename... Args>
74+inline int snprintf(char *s, size_t maxlen, const char *format) {
75+ std::strncpy(s, format, maxlen);
76+ s[maxlen-1] = 0;
77+ return strlen(s);
78+}
79+
80+template<typename... Args>
81+inline std::string format() { return std::string(); }
82+
83+template<typename... Args>
84+inline std::string format(const std::string& format) { return format; }
85+
86+// Format strings with the sprintf style, accepting std::string and string convertible types for %s
87+template<typename... Args>
88+std::string format(const std::string& format, const Args&... args) {
89+ int n = snprintf(NULL, 0, format.c_str(), args...);
90+ VALIDATE(n != -1);
91+ std::string buffer(n + 1, '\0');
92+ n = snprintf(&buffer[0], buffer.size(), format.c_str(), args...);
93+ VALIDATE(n != -1);
94+ buffer.resize(n);
95+ return buffer;
96+}
97+
98+}
99+
100+#endif
A RD_Client/src/framework/stdext/math.cpp +69-0 View file
@@ -0,0 +1,69 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#include "math.h"
24+#include <random>
25+
26+#ifdef _MSC_VER
27+ #pragma warning(disable:4267) // '?' : conversion from 'A' to 'B', possible loss of data
28+#endif
29+
30+namespace stdext {
31+
32+uint32_t adler32(const uint8_t *buffer, size_t size) {
33+ size_t a = 1, b = 0, tlen;
34+ while(size > 0) {
35+ tlen = size > 5552 ? 5552 : size;
36+ size -= tlen;
37+ do {
38+ a += *buffer++;
39+ b += a;
40+ } while (--tlen);
41+
42+ a %= 65521;
43+ b %= 65521;
44+ }
45+ return (b << 16) | a;
46+}
47+
48+long random_range(long min, long max)
49+{
50+ static std::random_device rd;
51+ static std::mt19937 gen(rd());
52+ static std::uniform_int_distribution<long> dis(0, 2147483647);
53+ return min + (dis(gen) % (max - min + 1));
54+}
55+
56+float random_range(float min, float max)
57+{
58+ static std::random_device rd;
59+ static std::mt19937 gen(rd());
60+ static std::uniform_real_distribution<float> dis(0.0, 1.0);
61+ return min + (max - min)*dis(gen);
62+}
63+
64+double round(double r)
65+{
66+ return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5);
67+}
68+
69+}
A RD_Client/src/framework/stdext/math.h +62-0 View file
@@ -0,0 +1,62 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifndef STDEXT_MATH_H
24+#define STDEXT_MATH_H
25+
26+#include <algorithm>
27+#include "types.h"
28+
29+namespace stdext {
30+
31+inline bool is_power_of_two(size_t v) { return ((v != 0) && !(v & (v - 1))); }
32+inline size_t to_power_of_two(size_t v) { if(v == 0) return 0; size_t r = 1; while(r < v && r != 0xffffffff) r <<= 1; return r; }
33+
34+inline uint16_t readULE16(const uchar *addr) { return (uint16_t)addr[1] << 8 | addr[0]; }
35+inline uint32_t readULE32(const uchar *addr) { return (uint32_t)readULE16(addr + 2) << 16 | readULE16(addr); }
36+inline uint64_t readULE64(const uchar *addr) { return (uint64_t)readULE32(addr + 4) << 32 | readULE32(addr); }
37+
38+inline void writeULE16(uchar *addr, uint16_t value) { addr[1] = value >> 8; addr[0] = (uint8_t)value; }
39+inline void writeULE32(uchar *addr, uint32_t value) { writeULE16(addr + 2, value >> 16); writeULE16(addr, (uint16_t)value); }
40+inline void writeULE64(uchar *addr, uint64_t value) { writeULE32(addr + 4, value >> 32); writeULE32(addr, (uint32_t)value); }
41+
42+inline int16_t readSLE16(const uchar *addr) { return (int16_t)addr[1] << 8 | addr[0]; }
43+inline int32_t readSLE32(const uchar *addr) { return (int32_t)readSLE16(addr + 2) << 16 | readSLE16(addr); }
44+inline int64_t readSLE64(const uchar *addr) { return (int64_t)readSLE32(addr + 4) << 32 | readSLE32(addr); }
45+
46+inline void writeSLE16(uchar *addr, int16_t value) { addr[1] = value >> 8; addr[0] = (int8_t)value; }
47+inline void writeSLE32(uchar *addr, int32_t value) { writeSLE16(addr + 2, value >> 16); writeSLE16(addr, (int16_t)value); }
48+inline void writeSLE64(uchar *addr, int64_t value) { writeSLE32(addr + 4, value >> 32); writeSLE32(addr, (int32_t)value); }
49+
50+uint32_t adler32(const uint8_t *buffer, size_t size);
51+
52+long random_range(long min, long max);
53+float random_range(float min, float max);
54+
55+double round(double r);
56+
57+template<typename T>
58+T clamp(T x, T min, T max) { return std::max<T>(min, std::min<T>(x, max)); }
59+
60+}
61+
62+#endif
A RD_Client/src/framework/stdext/net.cpp +60-0 View file
@@ -0,0 +1,60 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#include "net.h"
24+#include <boost/lexical_cast.hpp>
25+#include <boost/algorithm/string.hpp>
26+#include <boost/asio/ip/address_v4.hpp>
27+
28+namespace stdext {
29+
30+std::string ip_to_string(uint32 ip)
31+{
32+ ip = boost::asio::detail::socket_ops::network_to_host_long(ip);
33+ boost::asio::ip::address_v4 address_v4 = boost::asio::ip::address_v4(ip);
34+ return address_v4.to_string();
35+}
36+
37+uint32 string_to_ip(const std::string& string)
38+{
39+ boost::asio::ip::address_v4 address_v4 = boost::asio::ip::address_v4::from_string(string);
40+ return boost::asio::detail::socket_ops::host_to_network_long(address_v4.to_ulong());
41+}
42+
43+std::vector<uint32> listSubnetAddresses(uint32 address, uint8 mask)
44+{
45+ std::vector<uint32> list;
46+ if(mask < 32) {
47+ uint32 bitmask = (0xFFFFFFFF >> mask);
48+ for(uint32 i = 0; i <= bitmask; i++) {
49+ uint32 ip = boost::asio::detail::socket_ops::host_to_network_long((boost::asio::detail::socket_ops::network_to_host_long(address) & (~bitmask)) | i);
50+ if((ip >> 24) != 0 && (ip >> 24) != 0xFF)
51+ list.push_back(ip);
52+ }
53+ }
54+ else
55+ list.push_back(address);
56+
57+ return list;
58+}
59+
60+}
A RD_Client/src/framework/stdext/net.h +36-0 View file
@@ -0,0 +1,36 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifndef STDEXT_NET_H
24+#define STDEXT_NET_H
25+
26+#include "types.h"
27+#include <string>
28+#include <vector>
29+
30+namespace stdext {
31+ std::string ip_to_string(uint32 ip);
32+ uint32 string_to_ip(const std::string& string);
33+ std::vector<uint32> listSubnetAddresses(uint32 address, uint8 mask);
34+}
35+
36+#endif
A RD_Client/src/framework/stdext/packed_any.h +117-0 View file
@@ -0,0 +1,117 @@
1+/*
2+ * Copyright (c) 2010-2017 OTClient <https://github.com/edubart/otclient>
3+ *
4+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5+ * of this software and associated documentation files (the "Software"), to deal
6+ * in the Software without restriction, including without limitation the rights
7+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+ * copies of the Software, and to permit persons to whom the Software is
9+ * furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20+ * THE SOFTWARE.
21+ */
22+
23+#ifndef STDEXT_PACKEDANY_H
24+#define STDEXT_PACKEDANY_H
25+
26+#include <framework/global.h>
27+#include <algorithm>
28+#include <type_traits>
29+#include <typeinfo>
30+
31+namespace stdext {
32+
33+// disable memory alignment
34+#pragma pack(push,1)
35+
36+template<typename T>
37+struct can_pack_in_any : std::integral_constant<bool,
38+ (sizeof(T) <= sizeof(void*) && std::is_trivial<T>::value)> {};
39+
40+// improved to use less memory
41+class packed_any {
42+public:
43+ struct placeholder {
44+ virtual ~placeholder() { }
45+ virtual const std::type_info& type() const = 0;
46+ virtual placeholder* clone() const = 0;
47+ };
48+
49+ template<typename T>
50+ struct holder : public placeholder {
51+ holder(const T& value) : held(value) { }
52+ const std::type_info& type() const { return typeid(T); }
53+ placeholder* clone() const { return new holder(held); }
54+ T held;
55+ private:
56+ holder& operator=(const holder &);
57+ };
58+
59+ placeholder* content;
60+ bool scalar;
61+
62+ packed_any() :
63+ content(nullptr), scalar(false) { }
64+ packed_any(const packed_any& other) :
65+ content(!other.scalar && other.content ? other.content->clone() : other.content),
66+ scalar(other.scalar) { }
67+ template<typename T>
68+ packed_any(const T& value, typename std::enable_if<(can_pack_in_any<T>::value)>::type* = nullptr) :
69+ content(reinterpret_cast<placeholder*>(static_cast<std::size_t>(value))), scalar(true) { }
70+ template<typename T>
71+ packed_any(const T& value, typename std::enable_if<!(can_pack_in_any<T>::value)>::type* = nullptr) :
72+ content(new holder<T>(value)), scalar(false) { }
73+ ~packed_any()
74+ { if(!scalar && content) delete content; }
75+
76+ packed_any& swap(packed_any& rhs) { std::swap(content, rhs.content); std::swap(scalar, rhs.scalar); return *this; }
77+
78+ template<typename T> packed_any& operator=(const T& rhs) { packed_any(rhs).swap(*this); return *this; }
79+ packed_any& operator=(packed_any rhs) { rhs.swap(*this); return *this; }
80+
81+ bool empty() const { return !scalar && !content; }
82+ template<typename T> T cast() const;
83+ const std::type_info& type() const {
84+ if(!scalar)
85+ return content ? content->type() : typeid(void);
86+ else
87+ return typeid(std::size_t);
88+ }
89+};
90+
91+template<typename T>
92+typename std::enable_if<can_pack_in_any<T>::value, T>::type
93+packed_any_cast(const packed_any& operand) {
94+ VALIDATE(operand.scalar);
95+ union {
96+ T v;
97+ packed_any::placeholder* content;
98+ };
99+ content = operand.content;
100+ return v;
101+}
102+
103+template<typename T>
104+typename std::enable_if<!can_pack_in_any<T>::value, T>::type
105+packed_any_cast(const packed_any& operand) {
106+ VALIDATE(operand.type() == typeid(T));
107+ return static_cast<packed_any::holder<T>*>(operand.content)->held;
108+}
109+
110+template<typename T> T packed_any::cast() const { return packed_any_cast<T>(*this); }
111+
112+// restore memory alignment
113+#pragma pack(pop)
114+
115+}
116+
117+#endif
Top