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,111 @@
#include "CompositionLayersInitializer.hpp"
#include "Lottie/Private/MainThread/LayerContainers/CompLayers/NullCompositionLayer.hpp"
#include "Lottie/Private/MainThread/LayerContainers/CompLayers/ShapeCompositionLayer.hpp"
#include "Lottie/Private/MainThread/LayerContainers/CompLayers/PreCompositionLayer.hpp"
#include "Lottie/Private/MainThread/LayerContainers/CompLayers/ImageCompositionLayer.hpp"
#include "Lottie/Private/MainThread/LayerContainers/CompLayers/TextCompositionLayer.hpp"
namespace lottie {
std::vector<std::shared_ptr<CompositionLayer>> initializeCompositionLayers(
std::vector<std::shared_ptr<LayerModel>> const &layers,
std::shared_ptr<AssetLibrary> const &assetLibrary,
std::shared_ptr<LayerImageProvider> const &layerImageProvider,
std::shared_ptr<AnimationTextProvider> const &textProvider,
std::shared_ptr<AnimationFontProvider> const &fontProvider,
float frameRate
) {
std::vector<std::shared_ptr<CompositionLayer>> compositionLayers;
std::map<int, std::shared_ptr<CompositionLayer>> layerMap;
std::vector<std::shared_ptr<LayerModel>> childLayers;
for (const auto &layer : layers) {
if (layer->hidden) {
auto genericLayer = std::make_shared<NullCompositionLayer>(layer);
compositionLayers.push_back(genericLayer);
if (layer->index) {
layerMap.insert(std::make_pair(layer->index.value(), genericLayer));
}
} else if (layer->type == LayerType::Shape) {
auto shapeContainer = std::make_shared<ShapeCompositionLayer>(std::static_pointer_cast<ShapeLayerModel>(layer));
compositionLayers.push_back(shapeContainer);
if (layer->index) {
layerMap.insert(std::make_pair(layer->index.value(), shapeContainer));
}
} else if (layer->type == LayerType::Solid) {
auto shapeContainer = std::make_shared<ShapeCompositionLayer>(std::static_pointer_cast<SolidLayerModel>(layer));
compositionLayers.push_back(shapeContainer);
if (layer->index) {
layerMap.insert(std::make_pair(layer->index.value(), shapeContainer));
}
} else if (layer->type == LayerType::Precomp && assetLibrary) {
auto precompLayer = std::static_pointer_cast<PreCompLayerModel>(layer);
auto precompAssetIt = assetLibrary->precompAssets.find(precompLayer->referenceID);
if (precompAssetIt != assetLibrary->precompAssets.end()) {
auto precompContainer = std::make_shared<PreCompositionLayer>(
precompLayer,
*(precompAssetIt->second),
layerImageProvider,
textProvider,
fontProvider,
assetLibrary,
frameRate
);
compositionLayers.push_back(precompContainer);
if (layer->index) {
layerMap.insert(std::make_pair(layer->index.value(), precompContainer));
}
}
} else if (layer->type == LayerType::Image && assetLibrary) {
auto imageLayer = std::static_pointer_cast<ImageLayerModel>(layer);
auto imageAssetIt = assetLibrary->imageAssets.find(imageLayer->referenceID);
if (imageAssetIt != assetLibrary->imageAssets.end()) {
auto imageContainer = std::make_shared<ImageCompositionLayer>(
imageLayer,
Vector2D((*imageAssetIt->second).width, (*imageAssetIt->second).height)
);
compositionLayers.push_back(imageContainer);
if (layer->index) {
layerMap.insert(std::make_pair(layer->index.value(), imageContainer));
}
}
} else if (layer->type == LayerType::Text) {
auto textContainer = std::make_shared<TextCompositionLayer>(std::static_pointer_cast<TextLayerModel>(layer), textProvider, fontProvider);
compositionLayers.push_back(textContainer);
if (layer->index) {
layerMap.insert(std::make_pair(layer->index.value(), textContainer));
}
} else {
auto genericLayer = std::make_shared<NullCompositionLayer>(layer);
compositionLayers.push_back(genericLayer);
if (layer->index) {
layerMap.insert(std::make_pair(layer->index.value(), genericLayer));
}
}
if (layer->parent) {
childLayers.push_back(layer);
}
}
/// Now link children with their parents
for (const auto &layerModel : childLayers) {
if (!layerModel->index.has_value()) {
continue;
}
if (const auto parentID = layerModel->parent) {
auto childLayerIt = layerMap.find(layerModel->index.value());
if (childLayerIt != layerMap.end()) {
auto parentLayerIt = layerMap.find(parentID.value());
if (parentLayerIt != layerMap.end()) {
childLayerIt->second->transformNode()->setParentNode(parentLayerIt->second->transformNode());
}
}
}
}
return compositionLayers;
}
}
@@ -0,0 +1,23 @@
#ifndef CompositionLayersInitializer_hpp
#define CompositionLayersInitializer_hpp
#include "Lottie/Private/MainThread/LayerContainers/CompLayers/CompositionLayer.hpp"
#include "Lottie/Private/Model/Assets/AssetLibrary.hpp"
#include "Lottie/Private/MainThread/LayerContainers/Utility/LayerImageProvider.hpp"
#include "Lottie/Public/TextProvider/AnimationTextProvider.hpp"
#include "Lottie/Public/FontProvider/AnimationFontProvider.hpp"
namespace lottie {
std::vector<std::shared_ptr<CompositionLayer>> initializeCompositionLayers(
std::vector<std::shared_ptr<LayerModel>> const &layers,
std::shared_ptr<AssetLibrary> const &assetLibrary,
std::shared_ptr<LayerImageProvider> const &layerImageProvider,
std::shared_ptr<AnimationTextProvider> const &textProvider,
std::shared_ptr<AnimationFontProvider> const &fontProvider,
float frameRate
);
}
#endif /* CompositionLayersInitializer_hpp */
@@ -0,0 +1,5 @@
#include "LayerFontProvider.hpp"
namespace lottie {
}
@@ -0,0 +1,45 @@
#ifndef LayerFontProvider_hpp
#define LayerFontProvider_hpp
#include "Lottie/Public/FontProvider/AnimationFontProvider.hpp"
#include "Lottie/Private/MainThread/LayerContainers/CompLayers/TextCompositionLayer.hpp"
namespace lottie {
/// Connects a LottieFontProvider to a group of text layers
class LayerFontProvider {
public:
LayerFontProvider(std::shared_ptr<AnimationFontProvider> const &fontProvider) {
_fontProvider = fontProvider;
reloadTexts();
}
std::shared_ptr<AnimationFontProvider> const &fontProvider() const {
return _fontProvider;
}
void setFontProvider(std::shared_ptr<AnimationFontProvider> const &fontProvider) {
_fontProvider = fontProvider;
reloadTexts();
}
void addTextLayers(std::vector<std::shared_ptr<TextCompositionLayer>> const &layers) {
for (const auto &layer : layers) {
_textLayers.push_back(layer);
}
}
void reloadTexts() {
for (const auto &layer : _textLayers) {
layer->setFontProvider(_fontProvider);
}
}
private:
std::vector<std::shared_ptr<TextCompositionLayer>> _textLayers;
std::shared_ptr<AnimationFontProvider> _fontProvider;
};
}
#endif /* LayerFontProvider_hpp */
@@ -0,0 +1,5 @@
#include "LayerImageProvider.hpp"
namespace lottie {
}
@@ -0,0 +1,58 @@
#ifndef LayerImageProvider_hpp
#define LayerImageProvider_hpp
#include "Lottie/Public/ImageProvider/AnimationImageProvider.hpp"
#include "Lottie/Private/Model/Assets/ImageAsset.hpp"
#include "Lottie/Private/MainThread/LayerContainers/CompLayers/ImageCompositionLayer.hpp"
namespace lottie {
/// Connects a LottieImageProvider to a group of image layers
class LayerImageProvider {
public:
LayerImageProvider(std::shared_ptr<AnimationImageProvider> const &imageProvider, std::map<std::string, std::shared_ptr<ImageAsset>> const &assets) :
_imageProvider(imageProvider),
_imageAssets(assets) {
reloadImages();
}
std::shared_ptr<AnimationImageProvider> imageProvider() const {
return _imageProvider;
}
void setImageProvider(std::shared_ptr<AnimationImageProvider> const &imageProvider) {
_imageProvider = imageProvider;
reloadImages();
}
std::vector<std::shared_ptr<ImageCompositionLayer>> const &imageLayers() const {
return _imageLayers;
}
void addImageLayers(std::vector<std::shared_ptr<ImageCompositionLayer>> const &layers) {
for (const auto &layer : layers) {
auto it = _imageAssets.find(layer->imageReferenceID());
if (it != _imageAssets.end()) {
_imageLayers.push_back(layer);
}
}
}
void reloadImages() {
for (const auto &imageLayer : imageLayers()) {
auto it = _imageAssets.find(imageLayer->imageReferenceID());
if (it != _imageAssets.end()) {
imageLayer->setImage(_imageProvider->imageForAsset(*it->second));
}
}
}
private:
std::shared_ptr<AnimationImageProvider> _imageProvider;
std::vector<std::shared_ptr<ImageCompositionLayer>> _imageLayers;
std::map<std::string, std::shared_ptr<ImageAsset>> _imageAssets;
};
}
#endif /* LayerImageProvider_hpp */
@@ -0,0 +1,5 @@
#include "LayerTextProvider.hpp"
namespace lottie {
}
@@ -0,0 +1,45 @@
#ifndef LayerTextProvider_hpp
#define LayerTextProvider_hpp
#include "Lottie/Public/TextProvider/AnimationTextProvider.hpp"
#include "Lottie/Private/MainThread/LayerContainers/CompLayers/TextCompositionLayer.hpp"
namespace lottie {
/// Connects a LottieTextProvider to a group of text layers
class LayerTextProvider {
public:
LayerTextProvider(std::shared_ptr<AnimationTextProvider> const &textProvider) {
_textProvider = textProvider;
reloadTexts();
}
std::shared_ptr<AnimationTextProvider> const &textProvider() const {
return _textProvider;
}
void setTextProvider(std::shared_ptr<AnimationTextProvider> const &textProvider) {
_textProvider = textProvider;
reloadTexts();
}
void addTextLayers(std::vector<std::shared_ptr<TextCompositionLayer>> const &layers) {
for (const auto &layer : layers) {
_textLayers.push_back(layer);
}
}
void reloadTexts() {
for (const auto &layer : _textLayers) {
layer->setTextProvider(_textProvider);
}
}
private:
std::vector<std::shared_ptr<TextCompositionLayer>> _textLayers;
std::shared_ptr<AnimationTextProvider> _textProvider;
};
}
#endif /* LayerTextProvider_hpp */
@@ -0,0 +1,5 @@
#include "LayerTransformNode.hpp"
namespace lottie {
}
@@ -0,0 +1,205 @@
#ifndef LayerTransformNode_hpp
#define LayerTransformNode_hpp
#include "Lottie/Private/Model/Objects/Transform.hpp"
#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/NodePropertyMap.hpp"
#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/Protocols/KeypathSearchable.hpp"
#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/NodeProperty.hpp"
#include "Lottie/Private/MainThread/NodeRenderSystem/NodeProperties/ValueProviders/KeyframeInterpolator.hpp"
#include "Lottie/Private/MainThread/NodeRenderSystem/Protocols/AnimatorNode.hpp"
#include "Lottie/Private/MainThread/NodeRenderSystem/Protocols/NodeOutput.hpp"
#include "Lottie/Private/MainThread/NodeRenderSystem/Nodes/OutputNodes/PassThroughOutputNode.hpp"
namespace lottie {
class LayerTransformProperties: public KeypathSearchableNodePropertyMap {
public:
LayerTransformProperties(std::shared_ptr<Transform> transform) {
_anchor = std::make_shared<NodeProperty<Vector3D>>(std::make_shared<KeyframeInterpolator<Vector3D>>(transform->anchorPoint().keyframes));
_scale = std::make_shared<NodeProperty<Vector3D>>(std::make_shared<KeyframeInterpolator<Vector3D>>(transform->scale().keyframes));
_rotation = std::make_shared<NodeProperty<Vector1D>>(std::make_shared<KeyframeInterpolator<Vector1D>>(transform->rotation().keyframes));
_opacity = std::make_shared<NodeProperty<Vector1D>>(std::make_shared<KeyframeInterpolator<Vector1D>>(transform->opacity().keyframes));
std::map<std::string, std::shared_ptr<AnyNodeProperty>> propertyMap;
_keypathProperties.insert(std::make_pair("Anchor Point", _anchor));
_keypathProperties.insert(std::make_pair("Scale", _scale));
_keypathProperties.insert(std::make_pair("Rotation", _rotation));
_keypathProperties.insert(std::make_pair("Opacity", _opacity));
if (transform->positionX().has_value() && transform->positionY().has_value()) {
auto xPosition = std::make_shared<NodeProperty<Vector1D>>(std::make_shared<KeyframeInterpolator<Vector1D>>(transform->positionX()->keyframes));
auto yPosition = std::make_shared<NodeProperty<Vector1D>>(std::make_shared<KeyframeInterpolator<Vector1D>>(transform->positionY()->keyframes));
_keypathProperties.insert(std::make_pair("X Position", xPosition));
_keypathProperties.insert(std::make_pair("Y Position", yPosition));
_positionX = xPosition;
_positionY = yPosition;
_position = nullptr;
} else if (transform->position().has_value()) {
auto position = std::make_shared<NodeProperty<Vector3D>>(std::make_shared<KeyframeInterpolator<Vector3D>>(transform->position()->keyframes));
_keypathProperties.insert(std::make_pair("Position", position));
_position = position;
_positionX = nullptr;
_positionY = nullptr;
} else {
_position = nullptr;
_positionX = nullptr;
_positionY = nullptr;
}
for (const auto &it : _keypathProperties) {
_properties.push_back(it.second);
}
}
virtual ~LayerTransformProperties() = default;
virtual std::vector<std::shared_ptr<AnyNodeProperty>> &properties() override {
return _properties;
}
virtual std::vector<std::shared_ptr<KeypathSearchable>> const &childKeypaths() const override {
return _childKeypaths;
}
virtual std::string keypathName() const override {
return "Transform";
}
virtual std::map<std::string, std::shared_ptr<AnyNodeProperty>> keypathProperties() const override {
return _keypathProperties;
}
virtual std::shared_ptr<CALayer> keypathLayer() const override {
return nullptr;
}
std::shared_ptr<NodeProperty<Vector3D>> const &anchor() {
return _anchor;
}
std::shared_ptr<NodeProperty<Vector3D>> const &scale() {
return _scale;
}
std::shared_ptr<NodeProperty<Vector1D>> const &rotation() {
return _rotation;
}
std::shared_ptr<NodeProperty<Vector3D>> const &position() {
return _position;
}
std::shared_ptr<NodeProperty<Vector1D>> const &positionX() {
return _positionX;
}
std::shared_ptr<NodeProperty<Vector1D>> const &positionY() {
return _positionY;
}
std::shared_ptr<NodeProperty<Vector1D>> const &opacity() {
return _opacity;
}
private:
std::map<std::string, std::shared_ptr<AnyNodeProperty>> _keypathProperties;
std::vector<std::shared_ptr<KeypathSearchable>> _childKeypaths;
std::vector<std::shared_ptr<AnyNodeProperty>> _properties;
std::shared_ptr<NodeProperty<Vector3D>> _anchor;
std::shared_ptr<NodeProperty<Vector3D>> _scale;
std::shared_ptr<NodeProperty<Vector1D>> _rotation;
std::shared_ptr<NodeProperty<Vector3D>> _position;
std::shared_ptr<NodeProperty<Vector1D>> _positionX;
std::shared_ptr<NodeProperty<Vector1D>> _positionY;
std::shared_ptr<NodeProperty<Vector1D>> _opacity;
};
class LayerTransformNode: public AnimatorNode {
public:
LayerTransformNode(std::shared_ptr<Transform> transform) :
AnimatorNode(nullptr),
_transformProperties(std::make_shared<LayerTransformProperties>(transform)) {
_outputNode = std::make_shared<PassThroughOutputNode>(nullptr);
}
virtual ~LayerTransformNode() = default;
virtual std::shared_ptr<NodeOutput> outputNode() override {
return _outputNode;
}
virtual std::shared_ptr<KeypathSearchableNodePropertyMap> propertyMap() const override {
return _transformProperties;
}
virtual bool shouldRebuildOutputs(float frame) override {
return hasLocalUpdates() || hasUpstreamUpdates();
}
virtual void rebuildOutputs(float frame) override {
_opacity = ((float)_transformProperties->opacity()->value().value) * 0.01f;
Vector2D position(0.0, 0.0);
if (_transformProperties->position()) {
auto position3d = _transformProperties->position()->value();
position.x = position3d.x;
position.y = position3d.y;
} else if (_transformProperties->positionX() && _transformProperties->positionY()) {
position = Vector2D(
_transformProperties->positionX()->value().value,
_transformProperties->positionY()->value().value
);
}
Vector3D anchor = _transformProperties->anchor()->value();
Vector3D scale = _transformProperties->scale()->value();
_localTransform = Transform2D::makeTransform(
Vector2D(anchor.x, anchor.y),
position,
Vector2D(scale.x, scale.y),
_transformProperties->rotation()->value().value,
std::nullopt,
std::nullopt
);
if (parentNode() && parentNode()->asLayerTransformNode()) {
_globalTransform = _localTransform * parentNode()->asLayerTransformNode()->_globalTransform;
} else {
_globalTransform = _localTransform;
}
}
std::shared_ptr<LayerTransformProperties> const &transformProperties() {
return _transformProperties;
}
float opacity() {
return _opacity;
}
Transform2D const &globalTransform() {
return _globalTransform;
}
private:
std::shared_ptr<NodeOutput> _outputNode;
std::shared_ptr<LayerTransformProperties> _transformProperties;
float _opacity = 1.0;
Transform2D _localTransform = Transform2D::identity();
Transform2D _globalTransform = Transform2D::identity();
public:
virtual LayerTransformNode *asLayerTransformNode() override {
return this;
}
};
}
#endif /* LayerTransformNode_hpp */