Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
learn-ogads committed May 15, 2023
1 parent 8c09da3 commit 1e37626
Show file tree
Hide file tree
Showing 12 changed files with 463 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .gitignore
@@ -0,0 +1,6 @@
bin/
obj/
/packages/
riderModule.iml
/_ReSharper.Caches/
.idea/
11 changes: 11 additions & 0 deletions Core/CustomConsole.cs
@@ -0,0 +1,11 @@
namespace OfferSimulation.Core;

public static class CustomConsole
{
public static void WriteLine(string text, ConsoleColor color)
{
Console.ForegroundColor = color;
Console.WriteLine(text);
Console.ResetColor();
}
}
18 changes: 18 additions & 0 deletions IpAddress.cs
@@ -0,0 +1,18 @@
using System.Text.Json;

namespace OfferSimulation;

public static class IpAddress
{
/// <summary>
/// Gets the current users IP Address.
/// This IP is used for fetching offers from OGAds.
/// </summary>
public static async Task<string?> GetAsync()
{
using var client = new HttpClient();
var resp = await client.GetStringAsync("https://api.ipify.org/?format=json");
var json = JsonSerializer.Deserialize<Dictionary<string, string>>(resp);
return json?["ip"];
}
}
34 changes: 34 additions & 0 deletions Models/Offer.cs
@@ -0,0 +1,34 @@
using System.Text.Json.Serialization;

namespace OfferSimulation.Models;

public class Offer
{
[JsonPropertyName("offerid")]
public int OfferId { get; set; }
[JsonPropertyName("name")]
public string Name { get; set; }
[JsonPropertyName("name_short")]
public string NameShort { get; set; }
[JsonPropertyName("description")]
public string Description { get; set; }
[JsonPropertyName("adcopy")]
public string AdCopy { get; set; }
[JsonPropertyName("picture")]
public string Picture { get; set; }
[JsonPropertyName("payout")]
public string Payout { get; set; }
[JsonPropertyName("country")]
public string Country { get; set; }
[JsonPropertyName("device")]
public string Device { get; set; }
[JsonPropertyName("link")]
public string Link { get; set; }
[JsonPropertyName("epc")]
public string Epc { get; set; }

public override string ToString()
{
return NameShort;
}
}
13 changes: 13 additions & 0 deletions Models/OfferResponse.cs
@@ -0,0 +1,13 @@
using System.Text.Json.Serialization;

namespace OfferSimulation.Models;

public class OfferResponse
{
[JsonPropertyName("success")]
public bool Success { get; set; }
[JsonPropertyName("error")]
public object Error { get; set; }
[JsonPropertyName("offers")]
public List<Offer> Offers { get; set; }
}
15 changes: 15 additions & 0 deletions OfferSimulation.csproj
@@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<ApplicationIcon>icon.ico</ApplicationIcon>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Bogus" Version="34.0.2" />
</ItemGroup>

</Project>
16 changes: 16 additions & 0 deletions OfferSimulation.sln
@@ -0,0 +1,16 @@

Microsoft Visual Studio Solution File, Format Version 12.00
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OfferSimulation", "OfferSimulation.csproj", "{C7017427-2F50-4FBF-BC21-9102C2396B93}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C7017427-2F50-4FBF-BC21-9102C2396B93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C7017427-2F50-4FBF-BC21-9102C2396B93}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C7017427-2F50-4FBF-BC21-9102C2396B93}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C7017427-2F50-4FBF-BC21-9102C2396B93}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
46 changes: 46 additions & 0 deletions Offers.cs
@@ -0,0 +1,46 @@
using System.Net.Http.Headers;
using System.Text.Json;
using System.Web;
using OfferSimulation.Core;
using OfferSimulation.Models;

namespace OfferSimulation;

public class Offers
{
private readonly string _offerApi = "https://unlockcontent.net/api/v2";
private readonly string _userAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 14_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Mobile/15E148 Safari/604.1";

/// <summary>
/// Fetches offers from OGAds with the <c>_userAgent</c> and <c>IP address</c> provided.
/// This allows us to send real offers to the user.
/// </summary>
public async Task<List<Offer>> GetAsync(string apiKey, string ipAddress)
{
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", apiKey);

// Build URL with query parameters
var builder = new UriBuilder(_offerApi);
var query = HttpUtility.ParseQueryString(builder.Query);
query["ip"] = ipAddress;
query["user_agent"] = _userAgent;
query["ctype"] = "1";
builder.Query = query.ToString();

var url = builder.Uri.ToString();
try
{
var resp = await client.GetStringAsync(url);
var offers = JsonSerializer.Deserialize<OfferResponse>(resp);
return offers!.Offers;
}
catch (Exception)
{
CustomConsole.WriteLine("[ERROR] Failed to fetch offers from OGAds. Either you provided an invalid API key or the request timed out", ConsoleColor.Red);
Console.WriteLine("Press any key to continue...");
Console.ReadKey();
throw;
}
}
}
200 changes: 200 additions & 0 deletions PostbackUrl.cs
@@ -0,0 +1,200 @@
using System.Security.Cryptography;
using System.Text.RegularExpressions;
using System.Web;
using Bogus;
using OfferSimulation.Models;

namespace OfferSimulation;

public class PostbackUrl
{
private string _url;
private readonly Offer _offer;
private readonly string _ipAddress;
private readonly Faker _faker;

public PostbackUrl(string url, Offer offer, string ipAddress)
{
_url = url;
_offer = offer;
_ipAddress = ipAddress;
_faker = new Faker();
}

/// <summary>
/// Replaces all possible parameters in the URL and returns the updated URL
/// For example this would convert as follows:
/// https://website.com/postback.php?id={offer_id}&payout={payout}&ip={session_ip}&offer_name={offer_name}&datetime={datetime}&ran={ran}
/// https://website.com/postback.php?id=49377&payout=6.59&ip=0.0.0.0&offer_name=WWE+Champions&datetime=2023-05-11 12:14:04&ran=78639
/// </summary>
public string ReplaceAll()
{
ReplaceOfferId();
ReplaceOfferName();
ReplaceAffiliateId();
ReplaceSource();
ReplaceSessionIp();
ReplacePayout();
ReplaceDate();
ReplaceTime();
ReplaceDateTime();
ReplaceSessionTimeStamp();
ReplaceAffSub();
ReplaceAffSub2();
ReplaceAffSub3();
ReplaceAffSub4();
ReplaceAffSub5();
ReplaceRan();
return _url;
}

private void ReplaceOfferId() => _url = _url.Replace("{offer_id}", _offer.OfferId.ToString());

private void ReplaceOfferName() => _url = _url.Replace("{offer_name}", HttpUtility.UrlEncode(_offer.NameShort));

private void ReplaceAffiliateId()
{
var random = new Random();
var affId = random.Next(1, 100000);
_url = _url.Replace("{affiliate_id}", affId.ToString());
}

private void ReplaceSource()
{
if (_url.Contains("{source}"))
{
Console.Write("Provide the source or press enter to leave blank:");
var source = Console.ReadLine();
_url = _url.Replace("{source}", source);
}
}

private void ReplaceSessionIp() => _url = _url.Replace("{session_ip}", _ipAddress);

private void ReplacePayout() => _url = _url.Replace("{payout}", _offer.Payout);

private void ReplaceDate()
{
var date = DateTime.Now.ToString("yyyy-MM-dd");
_url = _url.Replace("{date}", date);
}

private void ReplaceTime()
{
var time = DateTime.Now.ToString("HH:mm:ss");
_url = _url.Replace("{time}", time);
}

private void ReplaceDateTime()
{
var dateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
_url = _url.Replace("{datetime}", dateTime);
}

private void ReplaceSessionTimeStamp()
{
var timestamp = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
_url = _url.Replace("{session_timestamp}", timestamp);
}

private void ReplaceAffSub()
{
_url = _url.Replace("{aff_sub}", "ContentLocker");
}

/// <summary>
/// AffSub2 is a randomly generated 5 numerical and character string.
/// This isn't the exact way OGAds does it, but it gives the end user the right idea.
/// </summary>
private void ReplaceAffSub2()
{
var bytes = RandomNumberGenerator.GetBytes(5);
var token = Convert.ToBase64String(bytes);

// Remove special characters and shorten string
var reg = new Regex("[*'\",_&#^@=]");
token = reg.Replace(token, string.Empty);
token = token[..5];

_url = _url.Replace("{aff_sub2}", token);
}

/// <summary>
/// AffSub3 is a long JWT token.
/// While this isn't a JWT token, it gives the end user the right idea.
/// </summary>
private void ReplaceAffSub3()
{
var bytes = RandomNumberGenerator.GetBytes(20);
var token = Convert.ToBase64String(bytes);

// Remove special characters and shorten string
var reg = new Regex("[*'\",_&#^@=]");
token = reg.Replace(token, string.Empty);

_url = _url.Replace("{aff_sub3}", token);
}

/// <summary>
/// AffSub4 is randomly generated or can be provided by the end user.
/// This only triggers if aff_sub4 is in the url.
/// </summary>
private void ReplaceAffSub4()
{
if (_url.Contains("{aff_sub4}"))
{
// Check if the user wants to manually provide or generate the aff_sub4
Console.Write("Generate aff_sub4? (y/n):");
var key = Console.ReadKey().Key;
Console.Write("\n");

string? affSub4;
if (key == ConsoleKey.N)
{
Console.Write("Provide aff_sub4, or press enter to leave blank:");
affSub4 = Console.ReadLine();
}
else
{
affSub4 = _faker.Internet.Email();
}

_url = _url.Replace("{aff_sub4}", affSub4);
}
}

/// <summary>
/// AffSub5 is randomly generated or provided by the user.
/// This only triggers if aff_sub5 is in the url.
/// </summary>
private void ReplaceAffSub5()
{
if (_url.Contains("{aff_sub5}"))
{
// Check if the user wants to manually provide or generate the aff_sub5
Console.Write("Generate aff_sub5? (y/n):");
var key = Console.ReadKey().Key;
Console.Write("\n");

string? affSub5;
if (key == ConsoleKey.N)
{
Console.WriteLine("Provide aff_sub5, or press enter to leave blank:");
affSub5 = Console.ReadLine();
}
else
{
affSub5 = _faker.Person.FirstName;
}

_url = _url.Replace("{aff_sub5}", affSub5);
}
}

private void ReplaceRan()
{
var random = new Random();
var ranNum = random.Next(1, 100000);
_url = _url.Replace("{ran}", ranNum.ToString());
}
}

0 comments on commit 1e37626

Please sign in to comment.