GLEGram 12.5 — Initial public release

Based on Swiftgram 12.5 (Telegram iOS 12.5).
All GLEGram features ported and organized in GLEGram/ folder.

Features: Ghost Mode, Saved Deleted Messages, Content Protection Bypass,
Font Replacement, Fake Profile, Chat Export, Plugin System, and more.

See CHANGELOG_12.5.md for full details.
This commit is contained in:
Leeksov
2026-04-06 09:48:12 +03:00
commit 4647310322
39685 changed files with 11052678 additions and 0 deletions
@@ -0,0 +1,5 @@
#include "DashElement.hpp"
namespace lottie {
}
@@ -0,0 +1,78 @@
#ifndef DashElement_hpp
#define DashElement_hpp
#include "Lottie/Private/Model/Keyframes/KeyframeGroup.hpp"
#include "Lottie/Private/Parsing/JsonParsing.hpp"
#include "Lottie/Public/Primitives/DashPattern.hpp"
namespace lottie {
enum class DashElementType {
Offset,
Dash,
Gap
};
class DashElement {
public:
DashElement(
DashElementType type_,
KeyframeGroup<Vector1D> const &value_
) :
type(type_),
value(value_) {
}
explicit DashElement(lottiejson11::Json::object const &json) noexcept(false) :
type(DashElementType::Offset),
value(KeyframeGroup<Vector1D>(Vector1D(0.0))) {
auto typeRawValue = getString(json, "n");
if (typeRawValue == "o") {
type = DashElementType::Offset;
} else if (typeRawValue == "d") {
type = DashElementType::Dash;
} else if (typeRawValue == "g") {
type = DashElementType::Gap;
} else {
throw LottieParsingException();
}
value = KeyframeGroup<Vector1D>(getObject(json, "v"));
name = getOptionalString(json, "nm");
}
lottiejson11::Json::object toJson() const {
lottiejson11::Json::object result;
switch (type) {
case DashElementType::Offset:
result.insert(std::make_pair("n", "o"));
break;
case DashElementType::Dash:
result.insert(std::make_pair("n", "d"));
break;
case DashElementType::Gap:
result.insert(std::make_pair("n", "g"));
break;
}
result.insert(std::make_pair("v", value.toJson()));
if (name.has_value()) {
result.insert(std::make_pair("nm", name.value()));
}
return result;
}
public:
DashElementType type;
KeyframeGroup<Vector1D> value;
std::optional<std::string> name;
};
}
#endif /* DashElement_hpp */
@@ -0,0 +1,5 @@
#include "FitzModifier.hpp"
namespace lottie {
}
@@ -0,0 +1,53 @@
#ifndef FitzModifier_hpp
#define FitzModifier_hpp
#include "Lottie/Private/Parsing/JsonParsing.hpp"
namespace lottie {
class FitzModifier {
public:
explicit FitzModifier(lottiejson11::Json::object const &json) noexcept(false) {
original = getInt(json, "o");
type12 = getOptionalInt(json, "f12");
type3 = getOptionalInt(json, "f3");
type4 = getOptionalInt(json, "f4");
type5 = getOptionalInt(json, "f5");
type6 = getOptionalInt(json, "f6");
}
lottiejson11::Json::object toJson() const {
lottiejson11::Json::object result;
result.insert(std::make_pair("o", (float)original));
if (type12.has_value()) {
result.insert(std::make_pair("f12", (float)type12.value()));
}
if (type3.has_value()) {
result.insert(std::make_pair("f3", (float)type3.value()));
}
if (type4.has_value()) {
result.insert(std::make_pair("f4", (float)type4.value()));
}
if (type5.has_value()) {
result.insert(std::make_pair("f5", (float)type5.value()));
}
if (type6.has_value()) {
result.insert(std::make_pair("f6", (float)type6.value()));
}
return result;
}
public:
float original;
std::optional<float> type12;
std::optional<float> type3;
std::optional<float> type4;
std::optional<float> type5;
std::optional<float> type6;
};
}
#endif /* FitzModifier_hpp */
@@ -0,0 +1,5 @@
#include "Marker.hpp"
namespace lottie {
}
@@ -0,0 +1,52 @@
#ifndef Marker_hpp
#define Marker_hpp
#include "Lottie/Public/Primitives/AnimationTime.hpp"
#include "Lottie/Private/Parsing/JsonParsing.hpp"
#include <string>
namespace lottie {
class Marker {
public:
Marker(
std::string const &name_,
AnimationFrameTime frameTime_
) :
name(name_),
frameTime(frameTime_) {
}
explicit Marker(lottiejson11::Json::object const &json) noexcept(false) {
name = getString(json, "cm");
frameTime = (float)getDouble(json, "tm");
dr = getOptionalInt(json, "dr");
}
lottiejson11::Json::object toJson() const {
lottiejson11::Json::object result;
result.insert(std::make_pair("cm", name));
result.insert(std::make_pair("tm", frameTime));
if (dr.has_value()) {
result.insert(std::make_pair("dr", dr.value()));
}
return result;
}
public:
/// The Marker Name
std::string name;
/// The Frame time of the marker
AnimationFrameTime frameTime;
std::optional<int> dr;
};
}
#endif /* Marker_hpp */
@@ -0,0 +1,5 @@
#include "Mask.hpp"
namespace lottie {
}
@@ -0,0 +1,139 @@
#ifndef Mask_hpp
#define Mask_hpp
#include "Lottie/Private/Model/Keyframes/KeyframeGroup.hpp"
#include <LottieCpp/BezierPath.h>
#include "Lottie/Private/Parsing/JsonParsing.hpp"
namespace lottie {
enum class MaskMode {
Add,
Subtract,
Intersect,
Lighten,
Darken,
Difference,
None
};
class Mask {
public:
explicit Mask(lottiejson11::Json::object const &json) noexcept(false) :
opacity(KeyframeGroup<Vector1D>(Vector1D(100.0))),
shape(KeyframeGroup<BezierPath>(BezierPath())),
inverted(false),
expansion(KeyframeGroup<Vector1D>(Vector1D(0.0))) {
if (const auto modeRawValue = getOptionalString(json, "mode")) {
if (modeRawValue.value() == "a") {
_mode = MaskMode::Add;
} else if (modeRawValue.value() == "s") {
_mode = MaskMode::Subtract;
} else if (modeRawValue.value() == "i") {
_mode = MaskMode::Intersect;
} else if (modeRawValue.value() == "l") {
_mode = MaskMode::Lighten;
} else if (modeRawValue.value() == "d") {
_mode = MaskMode::Darken;
} else if (modeRawValue.value() == "f") {
_mode = MaskMode::Difference;
} else if (modeRawValue.value() == "n") {
_mode = MaskMode::None;
} else {
throw LottieParsingException();
}
}
if (const auto opacityData = getOptionalObject(json, "o")) {
opacity = KeyframeGroup<Vector1D>(opacityData.value());
}
shape = KeyframeGroup<BezierPath>(getObject(json, "pt"));
if (const auto invertedData = getOptionalBool(json, "inv")) {
inverted = invertedData.value();
}
if (const auto expansionData = getOptionalObject(json, "x")) {
expansion = KeyframeGroup<Vector1D>(expansionData.value());
}
name = getOptionalString(json, "nm");
}
lottiejson11::Json::object toJson() const {
lottiejson11::Json::object result;
if (_mode.has_value()) {
switch (_mode.value()) {
case MaskMode::Add:
result.insert(std::make_pair("mode", "a"));
break;
case MaskMode::Subtract:
result.insert(std::make_pair("mode", "s"));
break;
case MaskMode::Intersect:
result.insert(std::make_pair("mode", "i"));
break;
case MaskMode::Lighten:
result.insert(std::make_pair("mode", "l"));
break;
case MaskMode::Darken:
result.insert(std::make_pair("mode", "d"));
break;
case MaskMode::Difference:
result.insert(std::make_pair("mode", "f"));
break;
case MaskMode::None:
result.insert(std::make_pair("mode", "n"));
break;
}
}
if (opacity.has_value()) {
result.insert(std::make_pair("o", opacity->toJson()));
}
result.insert(std::make_pair("pt", shape.toJson()));
if (inverted.has_value()) {
result.insert(std::make_pair("inv", inverted.value()));
}
if (expansion.has_value()) {
result.insert(std::make_pair("x", expansion->toJson()));
}
if (name.has_value()) {
result.insert(std::make_pair("nm", name.value()));
}
return result;
}
public:
MaskMode mode() const {
if (_mode.has_value()) {
return _mode.value();
} else {
return MaskMode::Add;
}
}
public:
std::optional<MaskMode> _mode;
std::optional<KeyframeGroup<Vector1D>> opacity;
KeyframeGroup<BezierPath> shape;
std::optional<bool> inverted;
std::optional<KeyframeGroup<Vector1D>> expansion;
std::optional<std::string> name;
};
}
#endif /* Mask_hpp */
@@ -0,0 +1,5 @@
#include "Transform.hpp"
namespace lottie {
}
@@ -0,0 +1,267 @@
#ifndef Transform_hpp
#define Transform_hpp
#include "Lottie/Private/Model/Keyframes/KeyframeGroup.hpp"
#include "Lottie/Private/Parsing/JsonParsing.hpp"
#include <optional>
namespace lottie {
class Transform {
public:
enum class PositionInternalRepresentation {
None,
TopLevelXY,
TopLevelCombined,
NestedXY
};
enum class RotationZInternalRepresentation {
RZ,
R
};
public:
Transform(
std::optional<KeyframeGroup<Vector3D>> anchorPoint_,
std::optional<KeyframeGroup<Vector3D>> position_,
std::optional<KeyframeGroup<Vector1D>> positionX_,
std::optional<KeyframeGroup<Vector1D>> positionY_,
std::optional<KeyframeGroup<Vector3D>> scale_,
std::optional<KeyframeGroup<Vector1D>> rotation_,
std::optional<KeyframeGroup<Vector1D>> &opacity_,
std::optional<KeyframeGroup<Vector1D>> rotationZ_
) :
_anchorPoint(anchorPoint_),
_position(position_),
_positionX(positionX_),
_positionY(positionY_),
_scale(scale_),
_rotation(rotation_),
_opacity(opacity_),
_rotationZ(rotationZ_) {
}
explicit Transform(lottiejson11::Json::object const &json) noexcept(false) {
// AnchorPoint
if (const auto anchorPointDictionary = getOptionalObject(json, "a")) {
_anchorPoint = KeyframeGroup<Vector3D>(anchorPointDictionary.value());
}
try {
auto xDictionary = getOptionalObject(json, "px");
auto yDictionary = getOptionalObject(json, "py");
if (xDictionary.has_value() && yDictionary.has_value()) {
_positionX = KeyframeGroup<Vector1D>(xDictionary.value());
_positionY = KeyframeGroup<Vector1D>(yDictionary.value());
_position = std::nullopt;
_positionInternalRepresentation = PositionInternalRepresentation::TopLevelXY;
} else if (const auto positionData = getOptionalObject(json, "p")) {
try {
LottieParsingException::Guard expectedGuard;
_position = KeyframeGroup<Vector3D>(positionData.value());
_positionX = std::nullopt;
_positionX = std::nullopt;
_positionInternalRepresentation = PositionInternalRepresentation::TopLevelCombined;
} catch(...) {
auto xData = getObject(positionData.value(), "x");
auto yData = getObject(positionData.value(), "y");
_positionX = KeyframeGroup<Vector1D>(xData);
_positionY = KeyframeGroup<Vector1D>(yData);
_position = std::nullopt;
_positionInternalRepresentation = PositionInternalRepresentation::NestedXY;
_extra_positionS = getOptionalBool(positionData.value(), "s");
}
} else {
_position = std::nullopt;
_positionX = std::nullopt;
_positionY = std::nullopt;
_positionInternalRepresentation = PositionInternalRepresentation::None;
}
} catch(...) {
throw LottieParsingException();
}
try {
// Scale
if (const auto scaleData = getOptionalObject(json, "s")) {
_scale = KeyframeGroup<Vector3D>(scaleData.value());
}
// Rotation
if (const auto rotationZData = getOptionalObject(json, "rz")) {
_rotationZ = KeyframeGroup<Vector1D>(rotationZData.value());
_rotationZInternalRepresentation = RotationZInternalRepresentation::RZ;
} else if (const auto rotationData = getOptionalObject(json, "r")) {
_rotation = KeyframeGroup<Vector1D>(rotationData.value());
_rotationZInternalRepresentation = RotationZInternalRepresentation::R;
}
// Opacity
if (const auto opacityData = getOptionalObject(json, "o")) {
_opacity = KeyframeGroup<Vector1D>(opacityData.value());
}
} catch(...) {
throw LottieParsingException();
}
_extraTy = getOptionalString(json, "ty");
_extraSa = getOptionalAny(json, "sa");
_extraSk = getOptionalAny(json, "sk");
}
lottiejson11::Json::object toJson() const {
lottiejson11::Json::object result;
if (_anchorPoint.has_value()) {
result.insert(std::make_pair("a", _anchorPoint->toJson()));
}
switch (_positionInternalRepresentation) {
case PositionInternalRepresentation::None:
assert(!_positionX.has_value());
assert(!_positionY.has_value());
assert(!_position.has_value());
break;
case PositionInternalRepresentation::TopLevelXY:
assert(_positionX.has_value());
assert(_positionY.has_value());
assert(!_position.has_value());
result.insert(std::make_pair("x", _positionX->toJson()));
result.insert(std::make_pair("y", _positionY->toJson()));
break;
case PositionInternalRepresentation::TopLevelCombined:
assert(_position.has_value());
assert(!_positionX.has_value());
assert(!_positionY.has_value());
result.insert(std::make_pair("p", _position->toJson()));
break;
case PositionInternalRepresentation::NestedXY:
lottiejson11::Json::object nestedPosition;
assert(_positionX.has_value());
assert(_positionY.has_value());
assert(!_position.has_value());
nestedPosition.insert(std::make_pair("x", _positionX->toJson()));
nestedPosition.insert(std::make_pair("y", _positionY->toJson()));
if (_extra_positionS.has_value()) {
nestedPosition.insert(std::make_pair("s", _extra_positionS.value()));
}
result.insert(std::make_pair("p", nestedPosition));
break;
}
if (_scale.has_value()) {
result.insert(std::make_pair("s", _scale->toJson()));
}
if (_rotation.has_value()) {
switch (_rotationZInternalRepresentation) {
case RotationZInternalRepresentation::RZ:
result.insert(std::make_pair("rz", _rotation->toJson()));
break;
case RotationZInternalRepresentation::R:
result.insert(std::make_pair("r", _rotation->toJson()));
break;
}
}
if (_opacity.has_value()) {
result.insert(std::make_pair("o", _opacity->toJson()));
}
if (_extraTy.has_value()) {
result.insert(std::make_pair("ty", _extraTy.value()));
}
if (_extraSa.has_value()) {
result.insert(std::make_pair("sa", _extraSa.value()));
}
if (_extraSk.has_value()) {
result.insert(std::make_pair("sk", _extraSk.value()));
}
return result;
}
KeyframeGroup<Vector3D> anchorPoint() {
if (_anchorPoint.has_value()) {
return _anchorPoint.value();
} else {
return KeyframeGroup<Vector3D>(Vector3D(0.0, 0.0, 0.0));
}
}
KeyframeGroup<Vector3D> scale() const {
if (_scale) {
return _scale.value();
} else {
return KeyframeGroup<Vector3D>(Vector3D(100.0, 100.0, 100.0));
}
}
KeyframeGroup<Vector1D> rotation() const {
if (_rotation) {
return _rotation.value();
} else {
return KeyframeGroup<Vector1D>(Vector1D(0.0));
}
}
KeyframeGroup<Vector1D> opacity() const {
if (_opacity) {
return _opacity.value();
} else {
return KeyframeGroup<Vector1D>(Vector1D(100.0));
}
}
std::optional<KeyframeGroup<Vector3D>> const &position() const {
return _position;
}
std::optional<KeyframeGroup<Vector1D>> const &positionX() const {
return _positionX;
}
std::optional<KeyframeGroup<Vector1D>> const &positionY() const {
return _positionY;
}
private:
/// The anchor point of the transform.
std::optional<KeyframeGroup<Vector3D>> _anchorPoint;
/// The position of the transform. This is nil if the position data was split.
std::optional<KeyframeGroup<Vector3D>> _position;
/// The positionX of the transform. This is nil if the position property is set.
std::optional<KeyframeGroup<Vector1D>> _positionX;
/// The positionY of the transform. This is nil if the position property is set.
std::optional<KeyframeGroup<Vector1D>> _positionY;
PositionInternalRepresentation _positionInternalRepresentation = PositionInternalRepresentation::None;
/// The scale of the transform
std::optional<KeyframeGroup<Vector3D>> _scale;
/// The rotation of the transform. Note: This is single dimensional rotation.
std::optional<KeyframeGroup<Vector1D>> _rotation;
/// The opacity of the transform.
std::optional<KeyframeGroup<Vector1D>> _opacity;
/// Should always be nil.
std::optional<KeyframeGroup<Vector1D>> _rotationZ;
RotationZInternalRepresentation _rotationZInternalRepresentation;
std::optional<bool> _extra_positionS;
std::optional<std::string> _extraTy;
std::optional<lottiejson11::Json> _extraSa;
std::optional<lottiejson11::Json> _extraSk;
};
}
#endif /* Transform_hpp */