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/ui/uiwidgetimage.cpp +248-0 View file
@@ -0,0 +1,248 @@
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 "uiwidget.h"
24+#include <framework/graphics/painter.h>
25+#include <framework/graphics/image.h>
26+#include <framework/graphics/texture.h>
27+#include <framework/graphics/texturemanager.h>
28+#include <framework/graphics/graphics.h>
29+#include <framework/util/crypt.h>
30+
31+void UIWidget::initImage()
32+{
33+}
34+
35+void UIWidget::parseImageStyle(const OTMLNodePtr& styleNode)
36+{
37+ for(const OTMLNodePtr& node : styleNode->children()) {
38+ if (node->tag() == "qr" || node->tag() == "qr-code")
39+ setQRCode(node->value(), 1);
40+ else if(node->tag() == "image-source")
41+ setImageSource(stdext::resolve_path(node->value(), node->source()));
42+ else if(node->tag() == "image-source-base64")
43+ setImageSourceBase64(node->value());
44+ else if(node->tag() == "image-offset-x")
45+ setImageOffsetX(node->value<int>());
46+ else if(node->tag() == "image-offset-y")
47+ setImageOffsetY(node->value<int>());
48+ else if(node->tag() == "image-offset")
49+ setImageOffset(node->value<Point>());
50+ else if(node->tag() == "image-width")
51+ setImageWidth(node->value<int>());
52+ else if(node->tag() == "image-height")
53+ setImageHeight(node->value<int>());
54+ else if(node->tag() == "image-size")
55+ setImageSize(node->value<Size>());
56+ else if(node->tag() == "image-rect")
57+ setImageRect(node->value<Rect>());
58+ else if(node->tag() == "image-clip")
59+ setImageClip(node->value<Rect>());
60+ else if(node->tag() == "image-fixed-ratio")
61+ setImageFixedRatio(node->value<bool>());
62+ else if(node->tag() == "image-repeated")
63+ setImageRepeated(node->value<bool>());
64+ else if(node->tag() == "image-smooth")
65+ setImageSmooth(node->value<bool>());
66+ else if(node->tag() == "image-color")
67+ setImageColor(node->value<Color>());
68+ else if(node->tag() == "image-border-top")
69+ setImageBorderTop(node->value<int>());
70+ else if(node->tag() == "image-border-right")
71+ setImageBorderRight(node->value<int>());
72+ else if(node->tag() == "image-border-bottom")
73+ setImageBorderBottom(node->value<int>());
74+ else if(node->tag() == "image-border-left")
75+ setImageBorderLeft(node->value<int>());
76+ else if(node->tag() == "image-border")
77+ setImageBorder(node->value<int>());
78+ else if(node->tag() == "image-auto-resize")
79+ setImageAutoResize(node->value<bool>());
80+ else if(node->tag() == "image-shader")
81+ setImageShader(node->value());
82+ }
83+}
84+
85+void UIWidget::drawImage(const Rect& screenCoords)
86+{
87+ if(!m_imageTexture || !screenCoords.isValid())
88+ return;
89+
90+ // cache vertex buffers
91+ if(m_imageCachedScreenCoords != screenCoords || m_imageMustRecache) {
92+ m_imageCoordsBuffer.clear();
93+ m_imageCachedScreenCoords = screenCoords;
94+ m_imageMustRecache = false;
95+
96+ Rect drawRect = screenCoords;
97+ drawRect.translate(m_imageRect.topLeft());
98+ if(m_imageRect.isValid())
99+ drawRect.resize(m_imageRect.size());
100+
101+ Rect clipRect = m_imageClipRect.isValid() ? m_imageClipRect : Rect(0, 0, m_imageTexture->getSize());
102+
103+ if(!m_imageBordered) {
104+ if(m_imageFixedRatio) {
105+ Size textureSize = m_imageTexture->getSize();
106+
107+ Size textureClipSize = drawRect.size();
108+ textureClipSize.scale(textureSize, Fw::KeepAspectRatio);
109+
110+ Point texCoordsOffset;
111+ if(textureSize.height() > textureClipSize.height())
112+ texCoordsOffset.y = (textureSize.height() - textureClipSize.height())/2;
113+ else if(textureSize.width() > textureClipSize.width())
114+ texCoordsOffset.x = (textureSize.width() - textureClipSize.width())/2;
115+
116+ Rect textureClipRect(texCoordsOffset, textureClipSize);
117+
118+ m_imageCoordsBuffer.addRect(drawRect, textureClipRect);
119+ } else {
120+ if(m_imageRepeated)
121+ m_imageCoordsBuffer.addRepeatedRects(drawRect, clipRect);
122+ else
123+ m_imageCoordsBuffer.addRect(drawRect, clipRect);
124+ }
125+ } else {
126+ int top = m_imageBorder.top;
127+ int bottom = m_imageBorder.bottom;
128+ int left = m_imageBorder.left;
129+ int right = m_imageBorder.right;
130+
131+ // calculates border coords
132+ const Rect clip = clipRect;
133+ Rect leftBorder(clip.left(), clip.top() + top, left, clip.height() - top - bottom);
134+ Rect rightBorder(clip.right() - right + 1, clip.top() + top, right, clip.height() - top - bottom);
135+ Rect topBorder(clip.left() + left, clip.top(), clip.width() - right - left, top);
136+ Rect bottomBorder(clip.left() + left, clip.bottom() - bottom + 1, clip.width() - right - left, bottom);
137+ Rect topLeftCorner(clip.left(), clip.top(), left, top);
138+ Rect topRightCorner(clip.right() - right + 1, clip.top(), right, top);
139+ Rect bottomLeftCorner(clip.left(), clip.bottom() - bottom + 1, left, bottom);
140+ Rect bottomRightCorner(clip.right() - right + 1, clip.bottom() - bottom + 1, right, bottom);
141+ Rect center(clip.left() + left, clip.top() + top, clip.width() - right - left, clip.height() - top - bottom);
142+ Size bordersSize(leftBorder.width() + rightBorder.width(), topBorder.height() + bottomBorder.height());
143+ Size centerSize = drawRect.size() - bordersSize;
144+ Rect rectCoords;
145+
146+ // first the center
147+ if(centerSize.area() > 0) {
148+ rectCoords = Rect(drawRect.left() + leftBorder.width(), drawRect.top() + topBorder.height(), centerSize);
149+ m_imageCoordsBuffer.addRepeatedRects(rectCoords, center);
150+ }
151+ // top left corner
152+ rectCoords = Rect(drawRect.topLeft(), topLeftCorner.size());
153+ m_imageCoordsBuffer.addRepeatedRects(rectCoords, topLeftCorner);
154+ // top
155+ rectCoords = Rect(drawRect.left() + topLeftCorner.width(), drawRect.topLeft().y, centerSize.width(), topBorder.height());
156+ m_imageCoordsBuffer.addRepeatedRects(rectCoords, topBorder);
157+ // top right corner
158+ rectCoords = Rect(drawRect.left() + topLeftCorner.width() + centerSize.width(), drawRect.top(), topRightCorner.size());
159+ m_imageCoordsBuffer.addRepeatedRects(rectCoords, topRightCorner);
160+ // left
161+ rectCoords = Rect(drawRect.left(), drawRect.top() + topLeftCorner.height(), leftBorder.width(), centerSize.height());
162+ m_imageCoordsBuffer.addRepeatedRects(rectCoords, leftBorder);
163+ // right
164+ rectCoords = Rect(drawRect.left() + leftBorder.width() + centerSize.width(), drawRect.top() + topRightCorner.height(), rightBorder.width(), centerSize.height());
165+ m_imageCoordsBuffer.addRepeatedRects(rectCoords, rightBorder);
166+ // bottom left corner
167+ rectCoords = Rect(drawRect.left(), drawRect.top() + topLeftCorner.height() + centerSize.height(), bottomLeftCorner.size());
168+ m_imageCoordsBuffer.addRepeatedRects(rectCoords, bottomLeftCorner);
169+ // bottom
170+ rectCoords = Rect(drawRect.left() + bottomLeftCorner.width(), drawRect.top() + topBorder.height() + centerSize.height(), centerSize.width(), bottomBorder.height());
171+ m_imageCoordsBuffer.addRepeatedRects(rectCoords, bottomBorder);
172+ // bottom right corner
173+ rectCoords = Rect(drawRect.left() + bottomLeftCorner.width() + centerSize.width(), drawRect.top() + topRightCorner.height() + centerSize.height(), bottomRightCorner.size());
174+ m_imageCoordsBuffer.addRepeatedRects(rectCoords, bottomRightCorner);
175+ }
176+ }
177+
178+ m_imageTexture->setSmooth(m_imageSmooth);
179+ if (!m_shader.empty()) {
180+ DrawQueueItemTextureCoords* thing = new DrawQueueItemImageWithShader(m_imageCoordsBuffer, m_imageTexture, m_imageColor, m_shader);
181+ g_drawQueue->add(thing);
182+ }
183+ else {
184+ g_drawQueue->addTextureCoords(m_imageCoordsBuffer, m_imageTexture, m_imageColor);
185+ }
186+}
187+
188+void UIWidget::setQRCode(const std::string& code, int border)
189+{
190+ m_imageTexture = TexturePtr(new Texture(Image::fromQRCode(code, border)));
191+ m_imageTexture->setCanCache(false);
192+
193+ if (m_imageTexture && (!m_rect.isValid() || m_imageAutoResize)) {
194+ Size size = getSize();
195+ Size imageSize = m_imageTexture->getSize();
196+ if (size.width() <= 0 || m_imageAutoResize)
197+ size.setWidth(imageSize.width());
198+ if (size.height() <= 0 || m_imageAutoResize)
199+ size.setHeight(imageSize.height());
200+ setSize(size);
201+ }
202+
203+ m_imageMustRecache = true;
204+}
205+
206+void UIWidget::setImageSource(const std::string& source)
207+{
208+ if(source.empty())
209+ m_imageTexture = nullptr;
210+ else
211+ m_imageTexture = g_textures.getTexture(source);
212+
213+ if(m_imageTexture && (!m_rect.isValid() || m_imageAutoResize)) {
214+ Size size = getSize();
215+ Size imageSize = m_imageTexture->getSize();
216+ if(size.width() <= 0 || m_imageAutoResize)
217+ size.setWidth(imageSize.width());
218+ if(size.height() <= 0 || m_imageAutoResize)
219+ size.setHeight(imageSize.height());
220+ setSize(size);
221+ }
222+
223+ m_imageMustRecache = true;
224+}
225+
226+void UIWidget::setImageSourceBase64(const std::string& data) {
227+ if (data.size() % 4 != 0 || data.empty()) {
228+ m_imageTexture = nullptr;
229+ m_imageMustRecache = true;
230+ return;
231+ }
232+
233+ std::stringstream stream;
234+ std::string decoded = g_crypt.base64Decode(data);
235+ stream.write(decoded.c_str(), decoded.size());
236+ m_imageTexture = g_textures.loadTexture(stream, "base64");
237+ if(m_imageTexture && (!m_rect.isValid() || m_imageAutoResize)) {
238+ Size size = getSize();
239+ Size imageSize = m_imageTexture->getSize();
240+ if(size.width() <= 0 || m_imageAutoResize)
241+ size.setWidth(imageSize.width());
242+ if(size.height() <= 0 || m_imageAutoResize)
243+ size.setHeight(imageSize.height());
244+ setSize(size);
245+ }
246+
247+ m_imageMustRecache = true;
248+}
A RD_Client/src/framework/ui/uiwidgettext.cpp +168-0 View file
@@ -0,0 +1,168 @@
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 "uiwidget.h"
24+#include "uitranslator.h"
25+#include <framework/graphics/fontmanager.h>
26+#include <framework/graphics/painter.h>
27+#include <framework/core/application.h>
28+
29+void UIWidget::initText()
30+{
31+ m_font = g_fonts.getDefaultFont();
32+ m_textAlign = Fw::AlignCenter;
33+}
34+
35+void UIWidget::updateText()
36+{
37+ if (m_textWrap && m_rect.isValid()) {
38+ m_drawTextColors = m_textColors;
39+ m_drawText = m_font->wrapText(m_text, getWidth() - m_textOffset.x, &m_drawTextColors);
40+ } else {
41+ m_drawText = m_text;
42+ m_drawTextColors = m_textColors;
43+ }
44+
45+ // update rect size
46+ if(!m_rect.isValid() || m_textHorizontalAutoResize || m_textVerticalAutoResize) {
47+ Size textBoxSize = getTextSize();
48+ textBoxSize += Size(m_padding.left + m_padding.right, m_padding.top + m_padding.bottom) + m_textOffset.toSize();
49+ Size size = getSize();
50+ if(size.width() <= 0 || (m_textHorizontalAutoResize && !m_textWrap))
51+ size.setWidth(textBoxSize.width());
52+ if(size.height() <= 0 || m_textVerticalAutoResize)
53+ size.setHeight(textBoxSize.height());
54+ setSize(size);
55+ }
56+
57+ m_textMustRecache = true;
58+}
59+
60+void UIWidget::parseTextStyle(const OTMLNodePtr& styleNode)
61+{
62+ for(const OTMLNodePtr& node : styleNode->children()) {
63+ if(node->tag() == "text")
64+ setText(node->value());
65+ else if(node->tag() == "text-align")
66+ setTextAlign(Fw::translateAlignment(node->value()));
67+ else if(node->tag() == "text-offset")
68+ setTextOffset(node->value<Point>());
69+ else if(node->tag() == "text-wrap")
70+ setTextWrap(node->value<bool>());
71+ else if(node->tag() == "text-auto-resize")
72+ setTextAutoResize(node->value<bool>());
73+ else if(node->tag() == "text-horizontal-auto-resize")
74+ setTextHorizontalAutoResize(node->value<bool>());
75+ else if(node->tag() == "text-vertical-auto-resize")
76+ setTextVerticalAutoResize(node->value<bool>());
77+ else if(node->tag() == "text-only-upper-case")
78+ setTextOnlyUpperCase(node->value<bool>());
79+ else if(node->tag() == "font")
80+ setFont(node->value());
81+ else if (node->tag() == "shadow")
82+ setShadow(node->value<bool>());
83+ }
84+}
85+
86+void UIWidget::drawText(const Rect& screenCoords)
87+{
88+ if(m_drawText.length() == 0 || m_color.aF() == 0.0f)
89+ return;
90+
91+ if(screenCoords != m_textCachedScreenCoords || m_textMustRecache) {
92+ Rect coords = Rect(screenCoords.topLeft() + m_textOffset, screenCoords.bottomRight());
93+ m_textMustRecache = false;
94+ m_textCachedScreenCoords = coords;
95+ }
96+
97+ if (!m_drawTextColors.empty()) {
98+ m_font->drawColoredText(m_drawText, m_textCachedScreenCoords, m_textAlign, m_drawTextColors, m_shadow);
99+ } else {
100+ m_font->drawText(m_drawText, m_textCachedScreenCoords, m_textAlign, m_color, m_shadow);
101+ }
102+}
103+
104+void UIWidget::onTextChange(const std::string& text, const std::string& oldText)
105+{
106+ callLuaField("onTextChange", text, oldText);
107+}
108+
109+void UIWidget::onFontChange(const std::string& font)
110+{
111+ callLuaField("onFontChange", font);
112+}
113+
114+void UIWidget::setText(std::string text, bool dontFireLuaCall)
115+{
116+ if(m_textOnlyUpperCase)
117+ stdext::toupper(text);
118+
119+ m_textColors.clear();
120+ m_drawTextColors.clear();
121+
122+ if(m_text == text)
123+ return;
124+
125+ std::string oldText = m_text;
126+ m_text = text;
127+ updateText();
128+
129+ if(!dontFireLuaCall) {
130+ onTextChange(text, oldText);
131+ }
132+}
133+
134+void UIWidget::setColoredText(const std::vector<std::string>& texts, bool dontFireLuaCall)
135+{
136+ m_textColors.clear();
137+ m_drawTextColors.clear();
138+
139+ std::string text = "";
140+ for(size_t i = 0, p = 0; i < texts.size() - 1; i += 2) {
141+ Color c(Color::white);
142+ stdext::cast<Color>(texts[i + 1], c);
143+ text += texts[i];
144+ for (auto& c : texts[i]) {
145+ if ((uint8)c >= 32)
146+ p += 1;
147+ }
148+ m_textColors.push_back(std::make_pair(p, c));
149+ }
150+
151+ if (m_textOnlyUpperCase)
152+ stdext::toupper(text);
153+
154+ std::string oldText = m_text;
155+ m_text = text;
156+ updateText();
157+
158+ if (!dontFireLuaCall) {
159+ onTextChange(text, oldText);
160+ }
161+}
162+
163+void UIWidget::setFont(const std::string& fontName)
164+{
165+ m_font = g_fonts.getFont(fontName);
166+ updateText();
167+ onFontChange(fontName);
168+}
A RD_Client/src/framework/util/color.cpp +145-0 View file
@@ -0,0 +1,145 @@
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 "color.h"
24+
25+// NOTE: AABBGGRR order
26+const Color Color::alpha = 0x00000000U;
27+const Color Color::white = 0xffffffff;
28+const Color Color::black = 0xff000000;
29+const Color Color::red = 0xff0000ff;
30+const Color Color::darkRed = 0xff000080;
31+const Color Color::green = 0xff00ff00;
32+const Color Color::darkGreen = 0xff008000;
33+const Color Color::blue = 0xffff0000;
34+const Color Color::darkBlue = 0xff800000;
35+const Color Color::pink = 0xffff00ff;
36+const Color Color::darkPink = 0xff800080;
37+const Color Color::yellow = 0xff00ffff;
38+const Color Color::darkYellow = 0xff008080;
39+const Color Color::teal = 0xffffff00;
40+const Color Color::darkTeal = 0xff808000;
41+const Color Color::gray = 0xffa0a0a0;
42+const Color Color::darkGray = 0xff808080;
43+const Color Color::lightGray = 0xffc0c0c0;
44+const Color Color::orange = 0xff008cff;
45+
46+Color::Color(const std::string& coltext)
47+{
48+ std::stringstream ss(coltext);
49+ ss >> *this;
50+}
51+
52+Color Color::getOutfitColor(int color)
53+{
54+ static const int HSI_SI_VALUES = 7;
55+ static const int HSI_H_STEPS = 19;
56+
57+ if (color >= HSI_H_STEPS * HSI_SI_VALUES)
58+ color = 0;
59+
60+ float loc1 = 0, loc2 = 0, loc3 = 0;
61+ if (color % HSI_H_STEPS != 0) {
62+ loc1 = color % HSI_H_STEPS * 1.0 / 18.0;
63+ loc2 = 1;
64+ loc3 = 1;
65+
66+ switch (int(color / HSI_H_STEPS)) {
67+ case 0:
68+ loc2 = 0.25;
69+ loc3 = 1.00;
70+ break;
71+ case 1:
72+ loc2 = 0.25;
73+ loc3 = 0.75;
74+ break;
75+ case 2:
76+ loc2 = 0.50;
77+ loc3 = 0.75;
78+ break;
79+ case 3:
80+ loc2 = 0.667;
81+ loc3 = 0.75;
82+ break;
83+ case 4:
84+ loc2 = 1.00;
85+ loc3 = 1.00;
86+ break;
87+ case 5:
88+ loc2 = 1.00;
89+ loc3 = 0.75;
90+ break;
91+ case 6:
92+ loc2 = 1.00;
93+ loc3 = 0.50;
94+ break;
95+ }
96+ } else {
97+ loc1 = 0;
98+ loc2 = 0;
99+ loc3 = 1 - (float)color / HSI_H_STEPS / (float)HSI_SI_VALUES;
100+ }
101+
102+ if (loc3 == 0)
103+ return Color(0, 0, 0);
104+
105+ if (loc2 == 0) {
106+ int loc7 = int(loc3 * 255);
107+ return Color(loc7, loc7, loc7);
108+ }
109+
110+ float red = 0, green = 0, blue = 0;
111+
112+ if (loc1 < 1.0 / 6.0) {
113+ red = loc3;
114+ blue = loc3 * (1 - loc2);
115+ green = blue + (loc3 - blue) * 6 * loc1;
116+ } else if (loc1 < 2.0 / 6.0) {
117+ green = loc3;
118+ blue = loc3 * (1 - loc2);
119+ red = green - (loc3 - blue) * (6 * loc1 - 1);
120+ } else if (loc1 < 3.0 / 6.0) {
121+ green = loc3;
122+ red = loc3 * (1 - loc2);
123+ blue = red + (loc3 - red) * (6 * loc1 - 2);
124+ } else if (loc1 < 4.0 / 6.0) {
125+ blue = loc3;
126+ red = loc3 * (1 - loc2);
127+ green = blue - (loc3 - red) * (6 * loc1 - 3);
128+ } else if (loc1 < 5.0 / 6.0) {
129+ blue = loc3;
130+ green = loc3 * (1 - loc2);
131+ red = green + (loc3 - green) * (6 * loc1 - 4);
132+ } else {
133+ red = loc3;
134+ green = loc3 * (1 - loc2);
135+ blue = red - (loc3 - green) * (6 * loc1 - 5);
136+ }
137+ return Color(int(red * 255), int(green * 255), int(blue * 255));
138+}
139+
140+std::string Color::toHex()
141+{
142+ std::stringstream ss;
143+ ss << *this;
144+ return ss.str();
145+}
A RD_Client/src/framework/util/color.h +222-0 View file
@@ -0,0 +1,222 @@
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 COLOR_H
24+#define COLOR_H
25+
26+#include "../stdext/types.h"
27+#include "../stdext/cast.h"
28+#include "../stdext/string.h"
29+#include "../const.h"
30+#include <iomanip>
31+#include <algorithm>
32+#include <sstream>
33+
34+class Color
35+{
36+public:
37+ Color() : m_r(1.0f), m_g(1.0f), m_b(1.0f), m_a(1.0f) { }
38+ Color(uint32 rgba) { setRGBA(rgba); }
39+ Color(uint8 r, uint8 g, uint8 b, uint8 a = 0xFF) : m_r(r/255.0f), m_g(g/255.0f), m_b(b/255.0f), m_a(a/255.0f) { }
40+ Color(int r, int g, int b, int a = 0xFF) : m_r(r/255.0f), m_g(g/255.0f), m_b(b/255.0f), m_a(a/255.0f) { }
41+ Color(float r, float g, float b, float a = 1.0f) : m_r(r), m_g(g), m_b(b), m_a(a) { }
42+ Color(const std::string& coltext);
43+
44+ uint8 a() const { return 255.0f * m_a; }
45+ uint8 b() const { return 255.0f * m_b; }
46+ uint8 g() const { return 255.0f * m_g; }
47+ uint8 r() const { return 255.0f * m_r; }
48+
49+ float aF() const { return m_a; }
50+ float bF() const { return m_b; }
51+ float gF() const { return m_g; }
52+ float rF() const { return m_r; }
53+
54+ void setRed(int r) { m_r = 0.003921f * r; }
55+ void setGreen(int g) { m_g = 0.003921f * g; }
56+ void setBlue(int b) { m_b = 0.003921f * b; }
57+ void setAlpha(int a) { m_a = 0.003921f * a; }
58+
59+ void setRed(float r) { m_r = r; }
60+ void setGreen(float g) { m_g = g; }
61+ void setBlue(float b) { m_b = b; }
62+ void setAlpha(float a) { m_a = a; }
63+
64+ void setRGBA(uint8 r, uint8 g, uint8 b, uint8 a = 0xFF) { m_r = r/255.0f; m_g = g/255.0f; m_b = b/255.0f; m_a = a/255.0f; }
65+ void setRGBA(uint32 rgba) { setRGBA((rgba >> 0) & 0xff, (rgba >> 8) & 0xff, (rgba >> 16) & 0xff, (rgba >> 24) & 0xff); }
66+
67+ Color opacity(float opacity) const {
68+ return Color(m_r, m_g, m_b, m_a * opacity);
69+ }
70+
71+ Color operator+(const Color& other) const { return Color(m_r + other.m_r, m_g + other.m_g, m_b + other.m_b, m_a + other.m_a); }
72+ Color operator-(const Color& other) const { return Color(m_r - other.m_r, m_g - other.m_g, m_b - other.m_b, m_a - other.m_a); }
73+
74+ Color operator*(float v) const { return Color(m_r*v, m_g*v, m_b*v, m_a*v); }
75+ Color operator/(float v) const { return Color(m_r/v, m_g/v, m_b/v, m_a/v); }
76+
77+ Color& operator=(uint32_t rgba) { setRGBA(rgba); return *this; }
78+
79+ Color operator+=(const Color& other) const {
80+ return Color(std::min<float>(1.0f, m_r + other.m_r), std::min<float>(1.0f, m_g + other.m_g),
81+ std::min<float>(1.0f, m_b + other.m_b), std::min<float>(1.0f, m_a + other.m_a));
82+ }
83+
84+ Color& operator=(const Color& other) { m_r = other.m_r; m_g = other.m_g; m_b = other.m_b; m_a = other.m_a; return *this; }
85+ bool operator==(const Color& other) const {
86+ if (std::abs(other.m_r - m_r) > 0.001) return false;
87+ if (std::abs(other.m_g - m_g) > 0.001) return false;
88+ if (std::abs(other.m_b - m_b) > 0.001) return false;
89+ if (std::abs(other.m_a - m_a) > 0.001) return false;
90+ return true;
91+ }
92+ bool operator!=(const Color& other) const { return !(other == *this); }
93+
94+ std::string toHex();
95+
96+ static uint8 to8bit(const Color& color) {
97+ uint8 c = 0;
98+ c += (color.r() / 51) * 36;
99+ c += (color.g() / 51) * 6;
100+ c += (color.b() / 51);
101+ return c;
102+ }
103+
104+ static Color from8bit(int color) {
105+ if(color >= 216 || color <= 0)
106+ return Color(0, 0, 0);
107+
108+ int r = int(color / 36) % 6 * 51;
109+ int g = int(color / 6) % 6 * 51;
110+ int b = color % 6 * 51;
111+ return Color(r, g, b);
112+ }
113+
114+ static Color getOutfitColor(int color);
115+
116+ static const Color alpha;
117+ static const Color white;
118+ static const Color black;
119+ static const Color red;
120+ static const Color darkRed;
121+ static const Color green;
122+ static const Color darkGreen;
123+ static const Color blue;
124+ static const Color darkBlue;
125+ static const Color pink;
126+ static const Color darkPink;
127+ static const Color yellow;
128+ static const Color darkYellow;
129+ static const Color teal;
130+ static const Color darkTeal;
131+ static const Color gray;
132+ static const Color darkGray;
133+ static const Color lightGray;
134+ static const Color orange;
135+
136+private:
137+ float m_r;
138+ float m_g;
139+ float m_b;
140+ float m_a;
141+};
142+
143+inline std::ostream& operator<<(std::ostream& out, const Color& color)
144+{
145+ using namespace std;
146+ out << "#" << hex << setfill('0')
147+ << setw(2) << (int)color.r()
148+ << setw(2) << (int)color.g()
149+ << setw(2) << (int)color.b()
150+ << setw(2) << (int)color.a();
151+ out << dec << setfill(' ');
152+ return out;
153+}
154+
155+inline std::istream& operator>>(std::istream& in, Color& color)
156+{
157+ using namespace std;
158+ std::string tmp;
159+
160+ if(in.get() == '#') {
161+ in >> tmp;
162+
163+ if(tmp.length() == 6 || tmp.length() == 8) {
164+ color.setRed((uint8)stdext::hex_to_dec(tmp.substr(0, 2)));
165+ color.setGreen((uint8)stdext::hex_to_dec(tmp.substr(2, 2)));
166+ color.setBlue((uint8)stdext::hex_to_dec(tmp.substr(4, 2)));
167+ if(tmp.length() == 8)
168+ color.setAlpha((uint8)stdext::hex_to_dec(tmp.substr(6, 2)));
169+ else
170+ color.setAlpha(255);
171+ } else
172+ in.seekg(-(std::streampos)tmp.length()-1, ios_base::cur);
173+ } else {
174+ in.unget();
175+ in >> tmp;
176+
177+ if(tmp == "alpha") {
178+ color = Color::alpha;
179+ } else if(tmp == "black") {
180+ color = Color::black;
181+ } else if(tmp == "white") {
182+ color = Color::white;
183+ } else if(tmp == "red") {
184+ color = Color::red;
185+ } else if(tmp == "darkRed") {
186+ color = Color::darkRed;
187+ } else if(tmp == "green") {
188+ color = Color::green;
189+ } else if(tmp == "darkGreen") {
190+ color = Color::darkGreen;
191+ } else if(tmp == "blue") {
192+ color = Color::blue;
193+ } else if(tmp == "darkBlue") {
194+ color = Color::darkBlue;
195+ } else if(tmp == "pink") {
196+ color = Color::pink;
197+ } else if(tmp == "darkPink") {
198+ color = Color::darkPink;
199+ } else if(tmp == "yellow") {
200+ color = Color::yellow;
201+ } else if(tmp == "darkYellow") {
202+ color = Color::darkYellow;
203+ } else if(tmp == "teal") {
204+ color = Color::teal;
205+ } else if(tmp == "darkTeal") {
206+ color = Color::darkTeal;
207+ } else if(tmp == "gray") {
208+ color = Color::gray;
209+ } else if(tmp == "darkGray") {
210+ color = Color::darkGray;
211+ } else if(tmp == "lightGray") {
212+ color = Color::lightGray;
213+ } else if(tmp == "orange") {
214+ color = Color::orange;
215+ } else {
216+ in.seekg(-tmp.length(), ios_base::cur);
217+ }
218+ }
219+ return in;
220+}
221+
222+#endif
A RD_Client/src/framework/util/crypt.cpp +526-0 View file
@@ -0,0 +1,526 @@
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 "crypt.h"
24+#include <framework/stdext/math.h>
25+#include <framework/core/logger.h>
26+#include <framework/core/resourcemanager.h>
27+#include <framework/platform/platform.h>
28+#include <framework/core/application.h>
29+
30+#include <boost/uuid/uuid_generators.hpp>
31+#include <boost/uuid/uuid_io.hpp>
32+#include <boost/functional/hash.hpp>
33+
34+#ifndef __EMSCRIPTEN__
35+#include <openssl/rsa.h>
36+#include <openssl/sha.h>
37+#include <openssl/md5.h>
38+#include <openssl/bn.h>
39+#include <openssl/err.h>
40+#endif
41+#include <zlib.h>
42+
43+static const std::string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
44+static inline bool is_base64(unsigned char c) { return (isalnum(c) || (c == '+') || (c == '/')); }
45+
46+Crypt g_crypt;
47+
48+Crypt::Crypt()
49+{
50+#ifndef __EMSCRIPTEN__
51+ m_rsa = RSA_new();
52+#endif
53+}
54+
55+Crypt::~Crypt()
56+{
57+#ifndef __EMSCRIPTEN__
58+ RSA_free(m_rsa);
59+#endif
60+}
61+
62+std::string Crypt::base64Encode(const std::string& decoded_string)
63+{
64+ std::string ret;
65+ int i = 0;
66+ int j = 0;
67+ uint8 char_array_3[3];
68+ uint8 char_array_4[4];
69+ int pos = 0;
70+ int len = decoded_string.size();
71+
72+ while(len--) {
73+ char_array_3[i++] = decoded_string[pos++];
74+ if(i == 3) {
75+ char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
76+ char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
77+ char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
78+ char_array_4[3] = char_array_3[2] & 0x3f;
79+
80+ for(i = 0; (i <4) ; i++)
81+ ret += base64_chars[char_array_4[i]];
82+ i = 0;
83+ }
84+ }
85+
86+ if(i) {
87+ for(j = i; j < 3; j++)
88+ char_array_3[j] = '\0';
89+
90+ char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
91+ char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
92+ char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
93+ char_array_4[3] = char_array_3[2] & 0x3f;
94+
95+ for(j = 0; (j < i + 1); j++)
96+ ret += base64_chars[char_array_4[j]];
97+
98+ while((i++ < 3))
99+ ret += '=';
100+ }
101+
102+ return ret;
103+}
104+
105+std::string Crypt::base64Decode(const std::string& encoded_string)
106+{
107+ int len = encoded_string.size();
108+ int i = 0;
109+ int j = 0;
110+ int in_ = 0;
111+ uint8 char_array_4[4], char_array_3[3];
112+ std::string ret;
113+
114+ while(len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
115+ char_array_4[i++] = encoded_string[in_]; in_++;
116+ if(i ==4) {
117+ for(i = 0; i <4; i++)
118+ char_array_4[i] = base64_chars.find(char_array_4[i]);
119+
120+ char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
121+ char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
122+ char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
123+
124+ for(i = 0; (i < 3); i++)
125+ ret += char_array_3[i];
126+ i = 0;
127+ }
128+ }
129+
130+ if(i) {
131+ for(j = i; j <4; j++)
132+ char_array_4[j] = 0;
133+
134+ for(j = 0; j <4; j++)
135+ char_array_4[j] = base64_chars.find(char_array_4[j]);
136+
137+ char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
138+ char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
139+ char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
140+
141+ for(j = 0; (j < i - 1); j++)
142+ ret += char_array_3[j];
143+ }
144+
145+ return ret;
146+}
147+
148+std::string Crypt::xorCrypt(const std::string& buffer, const std::string& key)
149+{
150+ std::string out;
151+ out.resize(buffer.size());
152+ size_t i, j=0;
153+ for(i=0;i<buffer.size();++i) {
154+ out[i] = buffer[i] ^ key[j++];
155+ if(j >= key.size())
156+ j = 0;
157+ }
158+ return out;
159+}
160+
161+std::string Crypt::genUUID()
162+{
163+ boost::uuids::random_generator gen;
164+ boost::uuids::uuid u = gen();
165+ return boost::uuids::to_string(u);
166+}
167+
168+bool Crypt::setMachineUUID(std::string uuidstr)
169+{
170+ if(uuidstr.empty())
171+ return false;
172+ uuidstr = _decrypt(uuidstr, false);
173+ if(uuidstr.length() != 16)
174+ return false;
175+ std::copy(uuidstr.begin(), uuidstr.end(), m_machineUUID.begin());
176+ return true;
177+}
178+
179+std::string Crypt::getMachineUUID()
180+{
181+ if(m_machineUUID.is_nil()) {
182+ boost::uuids::random_generator gen;
183+ m_machineUUID = gen();
184+ }
185+ return _encrypt(std::string(m_machineUUID.begin(), m_machineUUID.end()), false);
186+}
187+
188+std::string Crypt::getCryptKey(bool useMachineUUID)
189+{
190+ boost::hash<boost::uuids::uuid> uuid_hasher;
191+ boost::uuids::uuid uuid;
192+ if(useMachineUUID) {
193+ uuid = m_machineUUID;
194+ } else {
195+ boost::uuids::nil_generator nilgen;
196+ uuid = nilgen();
197+ }
198+ boost::uuids::name_generator namegen(uuid);
199+ boost::uuids::uuid u = namegen(g_app.getCompactName() + g_platform.getCPUName() + g_platform.getOSName());
200+ std::size_t hash = uuid_hasher(u);
201+ std::string key;
202+ key.assign((const char *)&hash, sizeof(hash));
203+ return key;
204+}
205+
206+std::string Crypt::_encrypt(const std::string& decrypted_string, bool useMachineUUID)
207+{
208+ std::string tmp = std::string("0000") + decrypted_string;
209+ uint32 sum = stdext::adler32((const uint8*)decrypted_string.c_str(), decrypted_string.size());
210+ stdext::writeULE32((uint8*)&tmp[0], sum);
211+ std::string encrypted = base64Encode(xorCrypt(tmp, getCryptKey(useMachineUUID)));
212+ return encrypted;
213+}
214+
215+std::string Crypt::_decrypt(const std::string& encrypted_string, bool useMachineUUID)
216+{
217+ std::string decoded = base64Decode(encrypted_string);
218+ std::string tmp = xorCrypt(decoded, getCryptKey(useMachineUUID));
219+ if(tmp.length() >= 4) {
220+ uint32 readsum = stdext::readULE32((const uint8*)tmp.c_str());
221+ std::string decrypted_string = tmp.substr(4);
222+ uint32 sum = stdext::adler32((const uint8*)decrypted_string.c_str(), decrypted_string.size());
223+ if(readsum == sum)
224+ return decrypted_string;
225+ }
226+ return std::string();
227+}
228+
229+std::string Crypt::md5Encode(const std::string& decoded_string, bool upperCase)
230+{
231+#ifndef __EMSCRIPTEN__
232+ MD5_CTX c;
233+ MD5_Init(&c);
234+ MD5_Update(&c, decoded_string.c_str(), decoded_string.length());
235+
236+ uint8_t md[MD5_DIGEST_LENGTH];
237+ MD5_Final(md, &c);
238+
239+ char output[(MD5_DIGEST_LENGTH << 1) + 1];
240+ for(int32_t i = 0; i < (int32_t)sizeof(md); ++i)
241+ sprintf(output + (i << 1), "%.2X", md[i]);
242+
243+ std::string result = output;
244+ if(upperCase)
245+ return result;
246+
247+ std::transform(result.begin(), result.end(), result.begin(), tolower);
248+ return result;
249+#else
250+ return "";
251+#endif
252+}
253+
254+std::string Crypt::sha1Encode(const std::string& decoded_string, bool upperCase)
255+{
256+#ifndef __EMSCRIPTEN__
257+ SHA_CTX c;
258+ SHA1_Init(&c);
259+ SHA1_Update(&c, decoded_string.c_str(), decoded_string.length());
260+
261+ uint8_t md[SHA_DIGEST_LENGTH];
262+ SHA1_Final(md, &c);
263+
264+ char output[(SHA_DIGEST_LENGTH << 1) + 1];
265+ for(int32_t i = 0; i < (int32_t)sizeof(md); ++i)
266+ sprintf(output + (i << 1), "%.2X", md[i]);
267+
268+ std::string result = output;
269+ if(upperCase)
270+ return result;
271+
272+ std::transform(result.begin(), result.end(), result.begin(), tolower);
273+ return result;
274+#else
275+ return "";
276+#endif
277+}
278+
279+std::string Crypt::sha256Encode(const std::string& decoded_string, bool upperCase)
280+{
281+#ifndef __EMSCRIPTEN__
282+ SHA256_CTX c;
283+ SHA256_Init(&c);
284+ SHA256_Update(&c, decoded_string.c_str(), decoded_string.length());
285+
286+ uint8_t md[SHA256_DIGEST_LENGTH];
287+ SHA256_Final(md, &c);
288+
289+ char output[(SHA256_DIGEST_LENGTH << 1) + 1];
290+ for(int32_t i = 0; i < (int32_t)sizeof(md); ++i)
291+ sprintf(output + (i << 1), "%.2X", md[i]);
292+
293+ std::string result = output;
294+ if(upperCase)
295+ return result;
296+
297+ std::transform(result.begin(), result.end(), result.begin(), tolower);
298+ return result;
299+#else
300+ return "";
301+#endif
302+}
303+
304+std::string Crypt::sha512Encode(const std::string& decoded_string, bool upperCase)
305+{
306+#ifndef __EMSCRIPTEN__
307+ SHA512_CTX c;
308+ SHA512_Init(&c);
309+ SHA512_Update(&c, decoded_string.c_str(), decoded_string.length());
310+
311+ uint8_t md[SHA512_DIGEST_LENGTH];
312+ SHA512_Final(md, &c);
313+
314+ char output[(SHA512_DIGEST_LENGTH << 1) + 1];
315+ for(int32_t i = 0; i < (int32_t)sizeof(md); ++i)
316+ sprintf(output + (i << 1), "%.2X", md[i]);
317+
318+ std::string result = output;
319+ if(upperCase)
320+ return result;
321+
322+ std::transform(result.begin(), result.end(), result.begin(), tolower);
323+ return result;
324+#else
325+ return "";
326+#endif
327+}
328+
329+std::string Crypt::crc32(const std::string& decoded_string, bool upperCase)
330+{
331+ uint32_t crc = ::crc32(0, Z_NULL, 0);
332+ crc = ::crc32(crc, (const Bytef*)decoded_string.c_str(), decoded_string.size());
333+ std::string result = stdext::dec_to_hex(crc);
334+ if (upperCase)
335+ std::transform(result.begin(), result.end(), result.begin(), toupper);
336+ else
337+ std::transform(result.begin(), result.end(), result.begin(), tolower);
338+ return result;
339+}
340+
341+
342+void Crypt::rsaGenerateKey(int bits, int e)
343+{
344+ // disabled because new OpenSSL changes broke
345+ /*
346+ RSA *rsa = RSA_new();
347+ BIGNUM *ebn = BN_new();
348+ BN_set_word(ebn, e);
349+ RSA_generate_key_ex(rsa, bits, ebn, nullptr);
350+ g_logger.info(stdext::format("%d bits (%d bytes) RSA key generated", bits, bits / 8));
351+ g_logger.info(std::string("p = ") + BN_bn2dec(m_rsa->p));
352+ g_logger.info(std::string("q = ") + BN_bn2dec(m_rsa->q));
353+ g_logger.info(std::string("d = ") + BN_bn2dec(m_rsa->d));
354+ g_logger.info(std::string("n = ") + BN_bn2dec(m_rsa->n));
355+ g_logger.info(std::string("e = ") + BN_bn2dec(m_rsa->e));
356+ BN_clear_free(ebn);
357+ RSA_free(rsa);
358+ */
359+}
360+
361+void Crypt::rsaSetPublicKey(const std::string& n, const std::string& e)
362+{
363+#ifndef __EMSCRIPTEN__
364+#if OPENSSL_VERSION_NUMBER < 0x10100005L
365+ BN_dec2bn(&m_rsa->n, n.c_str());
366+ BN_dec2bn(&m_rsa->e, e.c_str());
367+ // clear rsa cache
368+ if(m_rsa->_method_mod_n) {
369+ BN_MONT_CTX_free(m_rsa->_method_mod_n);
370+ m_rsa->_method_mod_n = nullptr;
371+ }
372+#else
373+ BIGNUM *bn = nullptr, *be = nullptr;
374+ BN_dec2bn(&bn, n.c_str());
375+ BN_dec2bn(&be, e.c_str());
376+ RSA_set0_key(m_rsa, bn, be, nullptr);
377+#endif
378+#endif
379+}
380+
381+void Crypt::rsaSetPrivateKey(const std::string& p, const std::string& q, const std::string& d)
382+{
383+#ifndef __EMSCRIPTEN__
384+#if OPENSSL_VERSION_NUMBER < 0x10100005L
385+ BN_dec2bn(&m_rsa->p, p.c_str());
386+ BN_dec2bn(&m_rsa->q, q.c_str());
387+ BN_dec2bn(&m_rsa->d, d.c_str());
388+ // clear rsa cache
389+ if(m_rsa->_method_mod_p) {
390+ BN_MONT_CTX_free(m_rsa->_method_mod_p);
391+ m_rsa->_method_mod_p = nullptr;
392+ }
393+ if(m_rsa->_method_mod_q) {
394+ BN_MONT_CTX_free(m_rsa->_method_mod_q);
395+ m_rsa->_method_mod_q = nullptr;
396+ }
397+#else
398+ BIGNUM *bp = nullptr, *bq = nullptr, *bd = nullptr;
399+ BN_dec2bn(&bp, p.c_str());
400+ BN_dec2bn(&bq, q.c_str());
401+ BN_dec2bn(&bd, d.c_str());
402+ RSA_set0_key(m_rsa, nullptr, nullptr, bd);
403+ RSA_set0_factors(m_rsa, bp, bq);
404+#endif
405+#endif
406+}
407+
408+bool Crypt::rsaCheckKey()
409+{
410+#ifndef __EMSCRIPTEN__
411+ // only used by server, that sets both public and private
412+ if(RSA_check_key(m_rsa)) {
413+ BN_CTX *ctx = BN_CTX_new();
414+ BN_CTX_start(ctx);
415+
416+ BIGNUM *r1 = BN_CTX_get(ctx), *r2 = BN_CTX_get(ctx);
417+#if OPENSSL_VERSION_NUMBER < 0x10100005L
418+ BN_mod(m_rsa->dmp1, m_rsa->d, r1, ctx);
419+ BN_mod(m_rsa->dmq1, m_rsa->d, r2, ctx);
420+ BN_mod_inverse(m_rsa->iqmp, m_rsa->q, m_rsa->p, ctx);
421+#else
422+ const BIGNUM *dmp1_c = nullptr, *d = nullptr, *dmq1_c = nullptr, *iqmp_c = nullptr, *q = nullptr, *p = nullptr;
423+
424+ RSA_get0_key(m_rsa, nullptr, nullptr, &d);
425+ RSA_get0_factors(m_rsa, &p, &q);
426+ RSA_get0_crt_params(m_rsa, &dmp1_c, &dmq1_c, &iqmp_c);
427+
428+ BIGNUM *dmp1 = BN_dup(dmp1_c), *dmq1 = BN_dup(dmq1_c), *iqmp = BN_dup(iqmp_c);
429+
430+ BN_mod(dmp1, d, r1, ctx);
431+ BN_mod(dmq1, d, r2, ctx);
432+ BN_mod_inverse(iqmp, q, p, ctx);
433+ RSA_set0_crt_params(m_rsa, dmp1, dmq1, iqmp);
434+#endif
435+ return true;
436+ }
437+ else {
438+ ERR_load_crypto_strings();
439+ g_logger.error(stdext::format("RSA check failed - %s", ERR_error_string(ERR_get_error(), nullptr)));
440+ return false;
441+ }
442+#else
443+ return false;
444+#endif
445+}
446+
447+bool Crypt::rsaEncrypt(unsigned char *msg, int size)
448+{
449+#ifndef __EMSCRIPTEN__
450+ if(size != RSA_size(m_rsa))
451+ return false;
452+ return RSA_public_encrypt(size, msg, msg, m_rsa, RSA_NO_PADDING) != -1;
453+#else
454+ return false;
455+#endif
456+}
457+
458+bool Crypt::rsaDecrypt(unsigned char *msg, int size)
459+{
460+#ifndef __EMSCRIPTEN__
461+ if(size != RSA_size(m_rsa))
462+ return false;
463+ return RSA_private_decrypt(size, msg, msg, m_rsa, RSA_NO_PADDING) != -1;
464+#else
465+ return false;
466+#endif
467+}
468+
469+int Crypt::rsaGetSize()
470+{
471+#ifndef __EMSCRIPTEN__
472+ return RSA_size(m_rsa);
473+#else
474+ return 0;
475+#endif
476+}
477+
478+#define DELTA 0x9e3779b9
479+#define MX (((z>>5^y<<2) + (y>>3^z<<4)) ^ ((sum^y) + (key[(p&3)^e] ^ z)))
480+#ifdef WITH_ENCRYPTION
481+void Crypt::bencrypt(uint8_t* buffer, int len, uint64_t k) {
482+ uint32_t const key[4] = { (uint32_t)(k >> 32), (uint32_t)(k & 0xFFFFFFFF), 0xDEADDEAD, 0xB00BEEEF };
483+ uint32_t y, z, sum;
484+ uint32_t *v = (uint32_t*)buffer;
485+ unsigned rounds, e;
486+ int p, n = (len - len % 4) / 4;
487+ if (n < 2)
488+ return;
489+ rounds = 6 + 52 / n;
490+ sum = 0;
491+ z = v[n - 1];
492+ do {
493+ sum += DELTA;
494+ e = (sum >> 2) & 3;
495+ for (p = 0; p < n - 1; p++) {
496+ y = v[p + 1];
497+ z = v[p] += MX;
498+ }
499+ y = v[0];
500+ z = v[n - 1] += MX;
501+ } while (--rounds);
502+}
503+#endif
504+
505+void Crypt::bdecrypt(uint8_t* buffer, int len, uint64_t k) {
506+ uint32_t const key[4] = { (uint32_t)(k >> 32), (uint32_t)(k & 0xFFFFFFFF), 0xDEADDEAD, 0xB00BEEEF };
507+ uint32_t y, z, sum;
508+ uint32_t *v = (uint32_t*)buffer;
509+ unsigned p, rounds, e;
510+ int n = (len - len % 4) / 4;
511+ if (n < 2)
512+ return;
513+ rounds = 6 + 52 / n;
514+ sum = rounds * DELTA;
515+ y = v[0];
516+ do {
517+ e = (sum >> 2) & 3;
518+ for (p = n - 1; p > 0; p--) {
519+ z = v[p - 1];
520+ y = v[p] -= MX;
521+ }
522+ z = v[n - 1];
523+ y = v[0] -= MX;
524+ sum -= DELTA;
525+ } while (--rounds);
526+}
A RD_Client/src/framework/util/crypt.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 CRYPT_H
24+#define CRYPT_H
25+
26+#include "../stdext/types.h"
27+#include <string>
28+
29+#include <boost/uuid/uuid.hpp>
30+
31+#ifndef __EMSCRIPTEN__
32+typedef struct rsa_st RSA;
33+#endif
34+
35+class Crypt
36+{
37+public:
38+ Crypt();
39+ ~Crypt();
40+
41+ std::string base64Encode(const std::string& decoded_string);
42+ std::string base64Decode(const std::string& encoded_string);
43+ std::string xorCrypt(const std::string& buffer, const std::string& key);
44+ std::string encrypt(const std::string& decrypted_string) { return _encrypt(decrypted_string, true); }
45+ std::string decrypt(const std::string& encrypted_string) { return _decrypt(encrypted_string, true); }
46+ std::string genUUID();
47+ bool setMachineUUID(std::string uuidstr);
48+ std::string getMachineUUID();
49+ std::string md5Encode(const std::string& decoded_string, bool upperCase);
50+ std::string sha1Encode(const std::string& decoded_string, bool upperCase);
51+ std::string sha256Encode(const std::string& decoded_string, bool upperCase);
52+ std::string sha512Encode(const std::string& decoded_string, bool upperCase);
53+ std::string crc32(const std::string& decoded_string, bool upperCase);
54+
55+ void rsaGenerateKey(int bits, int e);
56+ void rsaSetPublicKey(const std::string& n, const std::string& e);
57+ void rsaSetPrivateKey(const std::string &p, const std::string &q, const std::string &d);
58+ bool rsaCheckKey();
59+ bool rsaEncrypt(unsigned char *msg, int size);
60+ bool rsaDecrypt(unsigned char *msg, int size);
61+ int rsaGetSize();
62+#ifdef WITH_ENCRYPTION
63+ void bencrypt(uint8_t * buffer, int len, uint64_t k);
64+#endif
65+ void bdecrypt(uint8_t * buffer, int len, uint64_t k);
66+
67+private:
68+ std::string _encrypt(const std::string& decrypted_string, bool useMachineUUID);
69+ std::string _decrypt(const std::string& encrypted_string, bool useMachineUUID);
70+ std::string getCryptKey(bool useMachineUUID);
71+ boost::uuids::uuid m_machineUUID;
72+#ifndef __EMSCRIPTEN__
73+ RSA *m_rsa;
74+#endif
75+};
76+
77+extern Crypt g_crypt;
78+
79+#endif
A RD_Client/src/framework/util/databuffer.h +114-0 View file
@@ -0,0 +1,114 @@
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 DATABUFFER_H
24+#define DATABUFFER_H
25+
26+template<class T>
27+class DataBuffer
28+{
29+public:
30+ DataBuffer(uint res = 64) :
31+ m_size(0),
32+ m_capacity(res),
33+ m_buffer(new T[m_capacity]) { }
34+ ~DataBuffer() {
35+ if(m_buffer)
36+ delete[] m_buffer;
37+ }
38+
39+ DataBuffer(const DataBuffer<T>& d)
40+ {
41+ m_size = d.m_size;
42+ m_capacity = std::max<uint>(64, d.m_size * 2);
43+ m_buffer = new T[m_capacity];
44+ memcpy(m_buffer, d.m_buffer, sizeof(T) * m_size);
45+ }
46+ DataBuffer& operator=(const DataBuffer<T>& d) = delete;
47+
48+ inline void reset() { m_size = 0; }
49+ inline void clear() {
50+ m_size = 0;
51+ m_capacity = 0;
52+ delete[] m_buffer;
53+ m_buffer = nullptr;
54+ }
55+
56+ inline bool empty() const { return m_size == 0; }
57+ inline uint size() const { return m_size; }
58+ inline T *data() const { return m_buffer; }
59+
60+ inline const T& at(uint i) const { return m_buffer[i]; }
61+ inline const T& last() const { return m_buffer[m_size-1]; }
62+ inline const T& first() const { return m_buffer[0]; }
63+ inline const T& operator[](uint i) const { return m_buffer[i]; }
64+ inline T& operator[](uint i) { return m_buffer[i]; }
65+
66+ inline void reserve(uint n) {
67+ if(n > m_capacity) {
68+ T *buffer = new T[n];
69+ memcpy(buffer, m_buffer, m_size * sizeof(T));
70+ if(m_buffer)
71+ delete[] m_buffer;
72+ m_buffer = buffer;
73+ m_capacity = n;
74+ }
75+ }
76+
77+ inline void resize(uint n, T def = T()) {
78+ if(n == m_size)
79+ return;
80+ reserve(n);
81+ for(uint i=m_size;i<n;++i)
82+ m_buffer[i] = def;
83+ m_size = n;
84+ }
85+
86+ inline void grow(uint n, bool precise = false) {
87+ if(n <= m_size)
88+ return;
89+ if(n > m_capacity) {
90+ uint newcapacity = m_capacity;
91+ if (precise) {
92+ newcapacity = n;
93+ } else {
94+ do { newcapacity *= 4; } while (newcapacity < n);
95+ }
96+ reserve(newcapacity);
97+ }
98+ m_size = n;
99+ }
100+
101+ inline void add(const T& v) {
102+ grow(m_size + 1);
103+ m_buffer[m_size-1] = v;
104+ }
105+
106+ inline DataBuffer &operator<<(const T &t) { add(t); return *this; }
107+
108+private:
109+ uint m_size;
110+ uint m_capacity;
111+ T *m_buffer;
112+};
113+
114+#endif
A RD_Client/src/framework/util/extras.cpp +6-0 View file
@@ -0,0 +1,6 @@
1+#include "extras.h"
2+#include <numeric>
3+#include <algorithm>
4+#include <sstream>
5+
6+Extras g_extras;
A RD_Client/src/framework/util/extras.h +86-0 View file
@@ -0,0 +1,86 @@
1+#ifndef EXTRAS_H
2+#define EXTRAS_H
3+
4+#include <string>
5+#include <map>
6+#include <framework/core/logger.h>
7+#include <deque>
8+
9+constexpr bool default_value = true;
10+
11+#define DEFINE_OPTION(option, description) { m_options[ #option ] = std::make_pair(description, &(this -> option )); }
12+
13+class Extras {
14+public:
15+ Extras() {
16+ DEFINE_OPTION(limitedPolling, "Limited polling");
17+
18+ DEFINE_OPTION(debugWalking, "Debug walking");
19+ DEFINE_OPTION(debugPredictiveWalking, "Debug predictive walking");
20+ DEFINE_OPTION(debugPathfinding, "Debug path finding");
21+ DEFINE_OPTION(debugRender, "Debug render");
22+ DEFINE_OPTION(debugProxy, "Debug proxy");
23+ DEFINE_OPTION(showPredictions, "Show predictions");
24+ DEFINE_OPTION(debugWidgets, "Debug widgets");
25+
26+ DEFINE_OPTION(disablePredictiveWalking, "Disable predictive walking");
27+ }
28+
29+ bool botDetection = default_value;
30+
31+ bool newMapViewRendering = default_value;
32+ bool limitedPolling = default_value;
33+
34+ bool debugWalking = false;
35+ bool debugPredictiveWalking = false;
36+ bool debugPathfinding = false;
37+ bool debugRender = false;
38+ bool debugProxy = false;
39+ bool disablePredictiveWalking = false;
40+ bool showPredictions = false;
41+ bool debugWidgets = false;
42+
43+ int testMode = 0;
44+
45+ void set(const std::string& key, bool value) {
46+ auto it = m_options.find(key);
47+ if (it == m_options.end()) {
48+ g_logger.fatal(std::string("Invalid extraOptions key:") + key);
49+ return;
50+ }
51+ *(it->second.second) = value;
52+ }
53+
54+ bool get(const std::string& key) {
55+ auto it = m_options.find(key);
56+ if (it == m_options.end()) {
57+ g_logger.fatal(std::string("Invalid extraOptions key:") + key);
58+ return false;
59+ }
60+ return *(it->second.second);
61+ }
62+
63+ std::string getDescription(const std::string& key) {
64+ auto it = m_options.find(key);
65+ if (it == m_options.end()) {
66+ g_logger.fatal(std::string("Invalid extraOptions key:") + key);
67+ return "";
68+ }
69+ return it->second.first;
70+ }
71+
72+ std::vector<std::string> getAll() {
73+ std::vector<std::string> ret;
74+ for (auto& it : m_options)
75+ ret.push_back(it.first);
76+ return ret;
77+ }
78+
79+private:
80+ std::map<std::string, std::pair<std::string, bool*>> m_options;
81+ std::deque<ticks_t> framerRenderTimes;
82+};
83+
84+extern Extras g_extras;
85+
86+#endif
A RD_Client/src/framework/util/framecounter.h +26-0 View file
@@ -0,0 +1,26 @@
1+#include <atomic>
2+#include <list>
3+#include "../stdext/time.h"
4+
5+class FrameCounter {
6+public:
7+ void addFrame() // not thread-safe
8+ {
9+ ticks_t now = stdext::millis();
10+ m_framesList.push_back(now);
11+ m_frames += 1;
12+ while (m_framesList.front() + 1000 < now) {
13+ m_framesList.pop_front();
14+ m_frames -= 1;
15+ }
16+ }
17+
18+ int getFps() // thread safe
19+ {
20+ return m_frames.load();
21+ }
22+
23+private:
24+ std::list<ticks_t> m_framesList;
25+ std::atomic_int m_frames;
26+};
A RD_Client/src/framework/util/matrix.h +246-0 View file
@@ -0,0 +1,246 @@
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 MATRIX_H
24+#define MATRIX_H
25+
26+#include <array>
27+#include <cstring>
28+#include <initializer_list>
29+#include <sstream>
30+
31+template<int N, int M, typename T = float>
32+class Matrix
33+{
34+public:
35+ Matrix() { setIdentity(); }
36+ Matrix(int) {} // construct without initializing identity matrix
37+ Matrix(const Matrix<N,M,T>& other) = default;
38+ template<typename U>
39+ Matrix(const std::initializer_list<U>& values) { *this = values; }
40+ template<typename U>
41+ Matrix(const U *values) { *this = values; }
42+
43+ void setIdentity();
44+ bool isIdentity() const;
45+ void fill(T value);
46+
47+ Matrix<M,N,T> transposed() const;
48+ typename std::enable_if<N==M>::type transpose() { *this = transposed(); }
49+
50+ T *data() { return m[0]; }
51+ const T *data() const { return m[0]; }
52+
53+ T& operator()(int row, int column) { return m[row-1][column-1]; }
54+ T operator()(int row, int column) const { return m[row-1][column-1]; }
55+
56+ Matrix<N,M,T>& operator=(const Matrix<N,M,T>& other) = default;
57+ template<typename U>
58+ Matrix<N,M,T>& operator=(const std::initializer_list<U>& values);
59+ template<typename U>
60+ Matrix<N,M,T>& operator=(const U *values);
61+ Matrix<N,M,T>& operator+=(const Matrix<N,M,T>& other);
62+ Matrix<N,M,T>& operator-=(const Matrix<N,M,T>& other);
63+ Matrix<N,M,T>& operator*=(T factor);
64+ Matrix<N,M,T>& operator/=(T divisor);
65+ bool operator==(const Matrix<N,M,T>& other) const;
66+ bool operator!=(const Matrix<N,M,T>& other) const;
67+
68+private:
69+ T m[N][M];
70+};
71+
72+template<int N, int M, typename T>
73+void Matrix<N,M,T>::setIdentity() {
74+ for(int i=0;i<N;++i) {
75+ for(int j=0;j<M;++j) {
76+ if(i==j)
77+ m[i][j] = 1.0f;
78+ else
79+ m[i][j] = 0.0f;
80+ }
81+ }
82+}
83+
84+template<int N, int M, typename T>
85+bool Matrix<N,M,T>::isIdentity() const {
86+ for(int i=0;i<N;++i)
87+ for(int j=0;j<M;++j)
88+ if((i==j && m[i][j] != 1.0f) || (i!=j && m[i][j] != 0.0f))
89+ return false;
90+ return true;
91+}
92+
93+template<int N, int M, typename T>
94+void Matrix<N,M,T>::fill(T value) {
95+ for(int i=0;i<N;++i)
96+ for(int j=0;j<M;++j)
97+ m[i][j] = value;
98+}
99+
100+template<int N, int M, typename T>
101+Matrix<M,N,T> Matrix<N,M,T>::transposed() const {
102+ Matrix<M,N,T> result(1);
103+ for(int i=0;i<N;++i)
104+ for(int j=0;j<M;++j)
105+ result.m[j][i] = m[i][j];
106+ return result;
107+}
108+
109+template<int N, int M, typename T>
110+template<typename U>
111+Matrix<N,M,T>& Matrix<N,M,T>::operator=(const std::initializer_list<U>& values) {
112+ auto it = values.begin();
113+ for(int i=0;i<N;++i)
114+ for(int j=0;j<M;++j)
115+ m[i][j] = *(it++);
116+ return *this;
117+}
118+
119+template<int N, int M, typename T>
120+template<typename U>
121+Matrix<N,M,T>& Matrix<N,M,T>::operator=(const U *values) {
122+ for(int i=0;i<N;++i)
123+ for(int j=0;j<M;++j)
124+ m[i][j] = values[i*N + j];
125+ return *this;
126+}
127+
128+template<int N, int M, typename T>
129+Matrix<N,M,T>& Matrix<N,M,T>::operator+=(const Matrix<N,M,T>& other) {
130+ for(int i=0;i<N;++i)
131+ for(int j=0;j<M;++j)
132+ m[i][j] += other.m[i][j];
133+ return *this;
134+}
135+
136+template<int N, int M, typename T>
137+Matrix<N,M,T>& Matrix<N,M,T>::operator-=(const Matrix<N,M,T>& other) {
138+ for(int i=0;i<N;++i)
139+ for(int j=0;j<M;++j)
140+ m[i][j] -= other.m[i][j];
141+ return *this;
142+}
143+
144+template<int N, int M, typename T>
145+Matrix<N,M,T>& Matrix<N,M,T>::operator*=(T factor) {
146+ for(int i=0;i<N;++i)
147+ for(int j=0;j<M;++j)
148+ m[i][j] *= factor;
149+ return *this;
150+}
151+
152+template<int N, int M, typename T>
153+Matrix<N,M,T>& Matrix<N,M,T>::operator/=(T divisor) {
154+ for(int i=0;i<N;++i)
155+ for(int j=0;j<M;++j)
156+ m[i][j] /= divisor;
157+ return *this;
158+}
159+
160+template<int N, int M, typename T>
161+bool Matrix<N,M,T>::operator==(const Matrix<N,M,T>& other) const
162+{
163+ for(int i=0;i<N;++i)
164+ for(int j=0;j<M;++j)
165+ if(m[i][j] != other.m[i][j])
166+ return false;
167+ return true;
168+}
169+
170+template<int N, int M, typename T>
171+bool Matrix<N,M,T>::operator!=(const Matrix<N,M,T>& other) const
172+{
173+ return !(*this == other);
174+}
175+
176+template<int N, int M, typename T>
177+std::ostream& operator<<(std::ostream& out, const Matrix<N,M,T>& mat)
178+{
179+ for(int i=1;i<=N;++i) {
180+ for(int j=1;j<=M;++j) {
181+ out << mat(i,j);
182+ if(j != M)
183+ out << " ";
184+ }
185+ out << "\n";
186+ }
187+ return out;
188+}
189+
190+template<int N, int M, typename T>
191+std::istream& operator>>(std::istream& in, Matrix<N,M,T>& mat)
192+{
193+ for(int i=0;i<N;++i)
194+ for(int j=0;j<M;++j)
195+ in >> mat(i,j);
196+ return in;
197+}
198+
199+// faster comparing for 3x3 matrixes
200+template<>
201+inline bool Matrix<3,3,float>::operator==(const Matrix<3,3,float>& other) const
202+{
203+ return m[0][0] == other.m[0][0] && m[1][1] == other.m[1][1] &&
204+ m[2][1] == other.m[2][1] && m[2][0] == other.m[2][0] &&
205+ m[1][2] == other.m[1][2] && m[0][2] == other.m[0][2] &&
206+ m[1][0] == other.m[1][0] && m[0][1] == other.m[0][1] &&
207+ m[2][2] == other.m[2][2];
208+}
209+
210+template<int M, int N, int P, int Q, typename T>
211+Matrix<M, Q, T> operator*(const Matrix<M,N,T>& a, const Matrix<P,Q,T>& b)
212+{
213+ static_assert(N==P, "N==P");
214+ Matrix<M,Q,T> c(1);
215+ for(int i=1;i<=M;++i) {
216+ for(int j=1;j<=Q;++j) {
217+ T sum = 0;
218+ for(int k=1;k<=N;++k)
219+ sum += a(i,k) * b(k,j);
220+ c(i,j) = sum;
221+ }
222+ }
223+ return c;
224+}
225+
226+template<int M, int N, typename T>
227+Matrix<M, N, T> operator+(const Matrix<M,N,T>& a, const Matrix<M,N,T>& b) { Matrix<M,N,T> c(a); c += b; return c; }
228+
229+template<int M, int N, typename T>
230+Matrix<M, N, T> operator-(const Matrix<M,N,T>& a, const Matrix<M,N,T>& b) { Matrix<M,N,T> c(a); c -= b; return c; }
231+
232+template<int M, int N, typename T>
233+Matrix<M, N, T> operator*(const Matrix<M,N,T>& a, float b) { Matrix<M,N,T> c(a); c *= b; return c; }
234+
235+template<int M, int N, typename T>
236+Matrix<M, N, T> operator/(const Matrix<M,N,T>& a, float b) { Matrix<M,N,T> c = a; c /= b; return c; }
237+
238+typedef Matrix<4,4> Matrix4x4;
239+typedef Matrix<3,3> Matrix3x3;
240+typedef Matrix<2,2> Matrix2x2;
241+
242+typedef Matrix4x4 Matrix4;
243+typedef Matrix3x3 Matrix3;
244+typedef Matrix2x2 Matrix2;
245+
246+#endif
A RD_Client/src/framework/util/pngunpacker.cpp +32-0 View file
@@ -0,0 +1,32 @@
1+#include "pngunpacker.h"
2+
3+FileMetadata::FileMetadata(const FileStreamPtr& file)
4+{
5+ offset = file->getU32();
6+ fileSize = file->getU32();
7+ fileName = file->getString();
8+}
9+
10+std::unordered_map<uint32_t, std::string> PngUnpacker::unpack(const FileStreamPtr& file)
11+{
12+ std::unordered_map<uint32_t, std::string> data;
13+
14+ uint32_t entries = file->getU32();
15+ std::vector<FileMetadata> metadata;
16+ metadata.reserve(entries);
17+ for (uint32_t i = 0; i < entries; ++i) {
18+ metadata.emplace_back(file);
19+ }
20+
21+ uint pos = file->tell();
22+ for (const auto& fileMetadata : metadata) {
23+ uint32_t imageID = std::stoi(fileMetadata.getFileName());
24+ auto it = data.emplace(imageID, std::string(fileMetadata.getFileSize(), '\0'));
25+ if (!it.second)
26+ continue; // duplicated
27+ file->seek(pos + fileMetadata.getOffset());
28+ file->read(it.first->second.data(), fileMetadata.getFileSize());
29+ }
30+ return data;
31+}
32+
A RD_Client/src/framework/util/pngunpacker.h +29-0 View file
@@ -0,0 +1,29 @@
1+#ifndef __PNG_UNPACKER_H
2+#define __PNG_UNPACKER_H
3+
4+#include <framework/core/declarations.h>
5+#include <framework/core/filestream.h>
6+#include <framework/graphics/declarations.h>
7+
8+ /* File unpacking related */
9+class FileMetadata
10+{
11+public:
12+ FileMetadata(const FileStreamPtr& file);
13+
14+ const std::string& getFileName() const { return fileName; }
15+ uint32_t getOffset() const { return offset; }
16+ uint32_t getFileSize() const { return fileSize; }
17+private:
18+ std::string fileName;
19+ uint32_t offset = 0;
20+ uint32_t fileSize = 0;
21+};
22+
23+class PngUnpacker
24+{
25+public:
26+ static std::unordered_map<uint32_t, std::string> unpack(const FileStreamPtr& file);
27+};
28+
29+#endif
A RD_Client/src/framework/util/point.h +104-0 View file
@@ -0,0 +1,104 @@
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 POINT_H
24+#define POINT_H
25+
26+#include "../stdext/types.h"
27+#include <sstream>
28+#include <cmath>
29+
30+template<class T>
31+class TSize;
32+
33+template<class T>
34+class TPoint
35+{
36+public:
37+ TPoint() : x(0), y(0) {}
38+ TPoint(T x, T y) : x(x), y(y) { }
39+ TPoint(const TPoint<T>& other) : x(other.x), y(other.y) { }
40+
41+ bool isNull() const { return x==0 && y==0; }
42+ TSize<T> toSize() const { return TSize<T>(x, y); }
43+
44+ TPoint<T> operator-() const { return TPoint<T>(-x, -y); }
45+
46+ TPoint<T> operator+(const TPoint<T>& other) const { return TPoint<T>(x + other.x, y + other.y); }
47+ TPoint<T>& operator+=(const TPoint<T>& other) { x+=other.x; y+=other.y; return *this; }
48+ TPoint<T> operator-(const TPoint<T>& other) const { return TPoint<T>(x - other.x, y - other.y); }
49+ TPoint<T>& operator-=(const TPoint<T>& other) { x-=other.x; y-=other.y; return *this; }
50+ TPoint<T> operator*(const TPoint<T>& other) const { return TPoint<T>(x * other.x, y * other.y); }
51+ TPoint<T>& operator*=(const TPoint<T>& other) { x*=other.x; y*=other.y; return *this; }
52+ TPoint<T> operator/(const TPoint<T>& other) const { return TPoint<T>(x/other.x, y/other.y); }
53+ TPoint<T>& operator/=(const TPoint<T>& other) { x/=other.x; y/=other.y; return *this; }
54+
55+ TPoint<T> operator+(T other) const { return TPoint<T>(x + other, y + other); }
56+ TPoint<T>& operator+=(T other) { x+=other; y+=other; return *this; }
57+ TPoint<T> operator-(T other) const { return TPoint<T>(x - other, y - other); }
58+ TPoint<T>& operator-=(T other) { x-=other; y-=other; return *this; }
59+ TPoint<T> operator*(float v) const { return TPoint<T>(x*v, y*v); }
60+ TPoint<T>& operator*=(float v) { x*=v; y*=v; return *this; }
61+ TPoint<T> operator/(float v) const { return TPoint<T>(x/v, y/v); }
62+ TPoint<T>& operator/=(float v) { x/=v; y/=v; return *this; }
63+
64+ TPoint<T> operator&(int a) { return TPoint<T>(x & a, y & a); }
65+ TPoint<T>& operator&=(int a) { x &= a; y &= a; return *this; }
66+
67+ bool operator<=(const TPoint<T>&other) const { return x<=other.x || (x==other.x && y<=other.y); }
68+ bool operator>=(const TPoint<T>&other) const { return x>=other.x || (x==other.x && y>=other.y); }
69+ bool operator<(const TPoint<T>&other) const { return x<other.x || (x==other.x && y<other.y); }
70+ bool operator>(const TPoint<T>&other) const { return x>other.x || (x==other.x && y>other.y); }
71+
72+ TPoint<T>& operator=(const TPoint<T>& other) { x = other.x; y = other.y; return *this; }
73+ bool operator==(const TPoint<T>& other) const { return other.x==x && other.y==y; }
74+ bool operator!=(const TPoint<T>& other) const { return other.x!=x || other.y!=y; }
75+
76+ float length() const { return sqrt((float)(x*x + y*y)); }
77+ T manhattanLength() const { return std::abs(x) + std::abs(y); }
78+
79+ float distanceFrom(const TPoint<T>& other) const {
80+ return TPoint<T>(x - other.x, y - other.y).getLength();
81+ }
82+
83+ T x, y;
84+};
85+
86+typedef TPoint<int> Point;
87+typedef TPoint<float> PointF;
88+
89+template<class T>
90+std::ostream& operator<<(std::ostream& out, const TPoint<T>& point)
91+{
92+ out << point.x << " " << point.y;
93+ return out;
94+}
95+
96+template<class T>
97+std::istream& operator>>(std::istream& in, TPoint<T>& point)
98+{
99+ in >> point.x;
100+ in >> point.y;
101+ return in;
102+}
103+
104+#endif
Top