How top expire exe after certain date-time in unity - c#

I am developing unity build (exe) and trying to implement such an algorithm that expire my player after certain time (e.g., after one week or one month). Here is the complete tested code with one little (actually big) problem:
public class LocalLimitedDaysLicense : MonoBehaviour
{
float numberOfDays = 3;
public string currentDate;
bool isShowExpiryMessage;
void Awake()
{
string playerPrefKeyName = "PlayerStartDateKey";
currentDate = DateTime.Now.ToString();
string playerStartDate = PlayerPrefs.GetString(playerPrefKeyName, "");
if (!PlayerPrefs.HasKey(playerPrefKeyName))
{
Debug.Log("Player Start Date Setting");
PlayerPrefs.SetString(playerPrefKeyName, currentDate);
}
else
{
Debug.Log("Player Start Date already Set");
}
string playerPrefsSaveDate = PlayerPrefs.GetString(playerPrefKeyName);
DateTime today = DateTime.Now;
DateTime playerFirstActiveDate = Convert.ToDateTime(PlayerPrefs.GetString(playerPrefKeyName));
DateTime playerLimitDate = playerFirstActiveDate.AddDays(numberOfDays);
if (DateTime.Compare(today, playerLimitDate) > 0)//confirm that
{
Time.timeScale = 0;
isShowExpiryMessage = true;
}
if (DateTime.Compare(today, playerFirstActiveDate) < 0)//Confirm that user didn't change the date of system
{
Time.timeScale = 0;
isShowExpiryMessage = true;
}
}
void OnGUI()
{
if (isShowExpiryMessage)
{
GUI.Label(new Rect((Screen.width / 2) - 100, Screen.height / 2, 300, 100), "Sorry the exe has expired.!");
}
}
}
It truly halt the program if certain days passed in the build but the problem is, if the user removed the old build and installed the build again then it will allow three days again.

1.Create a web API that will register the date to the server database.
2.Create another API That returns true or false depending on your player expire logic and fire the API when the game starts every time.

It's not possible to control that from the client only.
By the way, there is another more simple flaw in your checking logic : user can simply change the date on its machine.
Do not try to enforce security features by trusting information from client only. Especially things that can be simply checked serverside.
As suggested by Reezoo Bose, you should implement some server-side checking.
(And if you want to prevent hacking this protection, you should also secure the communication with correct authentication and message signing. Of course it depends on which "tech level" users you are willing to protect your software against.)

Related

Add expiration to C# windows application

i am trying to make make app expire after some days using the registry option, i have successfully written and read from registry, my issue is to check for expiration, below is my code:
regKey = Registry.CurrentUser.OpenSubKey("Systemfiles");//subkeyname
if (regKey == null)
{
regKey = Registry.CurrentUser.CreateSubKey("Systemfiles");
regKey.SetValue("tere", Encrypt("4/16/2017"));
}
else
{
regKey = Registry.CurrentUser.OpenSubKey("Systemfiles");//subkeyname
string decryptDateValue = Decrypt(regKey.GetValue("tere").ToString()); //Keyname
DateTime mainDate = Convert.ToDateTime(decryptDateValue);
DateTime expiringDate = mainDate.AddDays(1);
if (mainDate > expiringDate)
{
expire = true;
}
else
{
//Continue execution
}
}
from my code i assumed the user's first run is the 04/16/2017, i also assumed i want the user to run the application for one day, which supposed to expire on the 04/17/2017, meaning if the user tries to start the application after 04/17/2017 the if part should execute, but i am not really getting it right, the else part always execute, i will appreciate a better way of doing it. Thanks
You've got this in your code:
DateTime expiringDate = mainDate.AddDays(1);
if (mainDate > expiringDate)
So,expiringDate would always be bigger than mainDate (one day exactly).
What you want to check is the actual Date, so it should be:
if (DateTime.Now>expiringDate)

Can I generate the compile date in my C# code to determine the expiry for a demo version?

I am creating a demonstration version of a C# program and I wish it to expire after a month.
// DEMO - Check date
DateTime expires = new DateTime(2016, 3, 16);
expires.AddMonths(2);
var diff = expires.Subtract(DateTime.Now);
if (diff.Days < 0)
{
MessageBox.Show("Demonstration expired.");
return;
}
I am wanting to have the date the compile instead of the hard coded new DateTime(2016, 3, 16);
Is there a compiler directive to give me the current date? Or am I aproaching this the wrong way?
But pre-processor directives are used during compile-time.
That expiration should be implemented using executable code. The issue here is you can hardcode it and hide it as much as possible, but it avid developers can find it and replace the intermediate language and generate a new assembly without the expiration. Actually, there're many other cases where an user can by-pass the whole expiration...
It seems like your best bet should be creating some kind of unique key, store it in your app and check if the whole key is still valid over the wire connecting to some licensing service developed by you.
An alternative solution to hard-coding a date that also offers some flexibility and extensibility could be to host a license file on a web server. For my sample, I used github. Create a well-known file for the application (possibly one for demo and a new one for beta1, etc.). At startup, and possibly periodically, read the file and parse it to determine applicability, timeouts, disable/enable features (like activating a custom warning message), etc.
Now you can ship your demo, put the expire date in the file, change it if needed, etc. This is not the most elegant nor secure solution, but for many use cases for a demo/beta, this might be enough to serve its intended purpose.
Below is a working mock-up of how this might look (omitted error checking and proper cleanup for brevity):
public class LicenseInfo
{
public string Info1 { get; private set; }
public bool IsValid
{
get
{
// todo, add logic here
return true;
}
}
public bool ParseLicense(string data)
{
bool ret = false;
if (data != null)
{
// todo, parse data and set status/attributes/etc
Info1 = data;
ret = true;
}
return ret;
}
}
// could make a static class...
public class License
{
public LicenseInfo GetLicenseInfo()
{
var license = new LicenseInfo();
// todo: create whatever schema you want.
// filename hard-coded per app/version/etc.
// file could contain text/json/etc.
// easy to manage, update, etc.
// extensible.
var uri = "https://raw.githubusercontent.com/korygill/Demo-License/master/StackOverflow-Demo-License.txt";
var request = (HttpWebRequest)HttpWebRequest.Create(uri);
var response = request.GetResponse();
var data = new StreamReader(response.GetResponseStream()).ReadToEnd();
license.ParseLicense(data);
return license;
}
}
class Program
{
static void Main(string[] args)
{
// check if our license if valid
var license = new License();
var licenseInfo = license.GetLicenseInfo();
if (!licenseInfo.IsValid)
{
Console.WriteLine("Sorry...license expired.");
Environment.Exit(1);
}
Console.WriteLine("You have a valid license.");
Console.WriteLine($"{licenseInfo.Info1}");
}
}

Adding a limit timer (Like can only be done/used every 24 hours)

Code for a command for a private server for a game I am "developing".
internal class LotteryCommand : Command
{
public LotteryCommand()
: base("lottery", 1)
{
}
//lottery can be used once every 24h, just to attract users making them want to get on at least once a day!
protected override bool Process(Player player, RealmTime time, string[] args)
{
Random rand = new Random();
string name = player.Name;
string lottonum = rand.Next(0, 100).ToString();
//50 50 chance!
if (int.Parse(lottonum) > 49)
{
player.Manager.Database.DoActionAsync(db =>
{
player.Credits = db.UpdateCredit(player.Client.Account, +5000);
player.UpdateCount++;
});
}
foreach (Client i in player.Manager.Clients.Values)
{
i.SendPacket(new TextPacket
{
BubbleTime = 0,
Stars = -1,
Name = "Lottery - " + name,
Text = "rolled a " + lottonum
});
}
return true;
}
}
can anyone tell me what to add if i wanted the command only to be used once per 24 hours?
for those who cant tell/wanna know, its /lottery, and will say "Lottery - Player has rolled a #" and if the # is 50 or higher, the player who used the command will win 5k gold (credits) and if below, they dont win anything.
i just want it to where it can only be used once every 24 hours.
Whenever a player runs that command you can insert a timestamp into the database. At the beginning of the command method, put a bit of code to check the database for that timestamp and see if it is within the last 24 hours. If it is, the break out of the method or put some functionality to alert the user they have played to often.
You can create another method called CanPlay that returns a bool, and pass it the user and the current timestamp. Use that method to determine if the user can play.

Google play error when making a purchase while implementing Soomla Unity3d plugin

I am creating an app that implements the Soomla Unity IAP plugin. In my effort to get the IAP to work, I have gotten to a point where I can make a purchase when in the editor. (Not a real purchase, it just updates the virtual currency that the user can buy/spend in game).
When I launch this on an Android device, I get this error: Authentication is required. You need to sign into your Google Account.
Now I have read multiple different articles where people have had this issue and nothing seems to be helping me.
Here is list of what I have tried so far:
1) Make sure app is published either to alpha or beta for testing.(in alpha now)
2) Make sure prices match for game and in developer console.
3) Use a device that is logged in as a user that is not using the developer email.
4) Make sure the email on the test device is listed as a tester in the developer console.
5) Make sure the necessary permissions are listed in the Android Manifest.
6) Confirm merchant account is set up correctly and verified.
7) Make sure to build as release and not development (not sure if this even matters, but I tried both ways).
8) Completely removed all of the Soomla plugin from the project and then added it back in while following the tutorial very closely just to makes sure nothing small was missed. Still no dice.
I have the core and store components added to the scene that they are necessary in. Please let me know if you have any other ideas of what I should do to fix this problem. In the mean time, here is the StoreAssets.cs code I use for setting up Soomla:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Soomla.Store;
public class StoreAssets : IStoreAssets
{
public static bool purchased = false;
public int GetVersion()
{
return 0;
}
public void onItemPurchased(PurchasableVirtualItem pvi, string payload)
{
purchased = true;
}
public VirtualCurrency[] GetCurrencies()
{
return new VirtualCurrency[]{TOKEN_CURRENCY};
}
public VirtualGood[] GetGoods()
{
return new VirtualGood[] {BACKUP_FORCEFIELD, IMMUNITY, EMP, MULTIPLIER};
}
public VirtualCurrencyPack[] GetCurrencyPacks()
{
return new VirtualCurrencyPack[] {FIVE_TOKEN_PACK, TEN_TOKEN_PACK, FIFTY_TOKEN_PACK};
}
public VirtualCategory[] GetCategories()
{
return new VirtualCategory[]{};
}
/** Virtual Currencies **/
public static VirtualCurrency TOKEN_CURRENCY = new VirtualCurrency
(
"Token", // Name
"Token currency", // Description
"token_currency_ID" // Item ID
);
/** Virtual Currency Packs **/
public static VirtualCurrencyPack FIVE_TOKEN_PACK = new VirtualCurrencyPack
(
"5 Tokens", // Name
"5 token currency units", // Description
"5_tokens_id", // Item ID
5, // Number of currencies in the pack
"token_currency_ID", // ID of the currency associated with this pack
new PurchaseWithMarket
( // Purchase type (with real money $)
"tokens_5_PROD_ID", // Product ID
0.99 // Price (in real money $)
)
);
public static VirtualCurrencyPack TEN_TOKEN_PACK = new VirtualCurrencyPack
(
"10 Tokens", // Name
"10 token currency units", // Description
"10_tokens_id", // Item ID
10, // Number of currencies in the pack
"token_currency_ID", // ID of the currency associated with this pack
new PurchaseWithMarket
( // Purchase type (with real money $)
"tokens_10_PROD_ID", // Product ID
1.99 // Price (in real money $)
)
);
public static VirtualCurrencyPack FIFTY_TOKEN_PACK = new VirtualCurrencyPack
(
"50 Tokens", // Name
"50 token currency units", // Description
"50_tokens_id", // Item ID
50, // Number of currencies in the pack
"token_currency_ID", // ID of the currency associated with this pack
new PurchaseWithMarket
( // Purchase type (with real money $)
"tokens_50_PROD_ID", // Product ID
4.99 // Price (in real money $)
)
);
/** Virtual Goods **/
public static VirtualGood BACKUP_FORCEFIELD = new SingleUseVG
(
"BackupForcefield", // Name
"Secondary forcefield for extra protection.", // Description
"bff_ID", // Item ID
new PurchaseWithVirtualItem
( // Purchase type (with virtual currency)
"token_currency_ID", // ID of the item used to pay with
1 // Price (amount of coins)
)
);
public static VirtualGood EMP = new SingleUseVG
(
"Emp", // Name
"Clear the surrounding space of all lasers.", // Description
"emp_ID", // Item ID
new PurchaseWithVirtualItem
( // Purchase type (with virtual currency)
"token_currency_ID", // ID of the item used to pay with
5 // Price (amount of coins)
)
);
public static VirtualGood IMMUNITY = new SingleUseVG
(
"Immunity", // Name
"Immune to damage.", // Description
"immunity_ID", // Item ID
new PurchaseWithVirtualItem
( // Purchase type (with virtual currency)
"token_currency_ID", // ID of the item used to pay with
10 // Price (amount of coins)
)
);
public static VirtualGood MULTIPLIER = new SingleUseVG
(
"Multiplier", // Name
"Double your score per deflected laser.", // Description
"multiplier_ID", // Item ID
new PurchaseWithVirtualItem
( // Purchase type (with virtual currency)
"token_currency_ID", // ID of the item used to pay with
15 // Price (amount of coins)
)
);
}
In order to purchase Items, I call:
StoreInventory.BuyItem("the id of my item");
To use an item that has been purchased, I call:
StoreInventory.TakeItem("the id of my item");
StoreInventory is a class that is included in Soomla when it is imported into Unity.
Here is the code where buying and item consumption is done:
public class Purchase : MonoBehaviour
{
public Text tokens;
public static bool bffFilled = false,
immFilled = false, empFilled = false,
multFilled = false, init = false;
void Start()
{
if (!init)
{
init = true;
SoomlaStore.Initialize(new StoreAssets());
}
Token.updateTokens (tokens);
}
void Update()
{
if (StoreEvents.balanceChanged)
{
StoreEvents.balanceChanged = false;
Token.updateTokens(tokens);
}
}
public void BuyItem (int item)
{
if (item == 1)
{
StoreInventory.BuyItem (StoreAssets.FIVE_TOKEN_PACK.ItemId);
}
else if (item == 2)
{
StoreInventory.BuyItem (StoreAssets.TEN_TOKEN_PACK.ItemId);
}
else if (item == 3)
{
StoreInventory.BuyItem (StoreAssets.FIFTY_TOKEN_PACK.ItemId);
}
Token.updateTokens(tokens);
}
public void getUpgrade(int upgrade)
{
if (upgrade == 1)
{
bool bffNotBought = PlayerPrefs.GetInt("Bff Available", 0) == 0;
if (StoreAssets.TOKEN_CURRENCY.GetBalance() >= 1 && bffNotBought)
{
PlayerPrefs.SetInt("Bff Available", 1);
PlayerPrefs.Save();
bffFilled = true;
StoreInventory.TakeItem(StoreAssets.TOKEN_CURRENCY.ItemId, 1);
}
}
else if (upgrade == 2)
{
bool empNotBought = PlayerPrefs.GetInt("Emp Available", 0) == 0;
if (StoreAssets.TOKEN_CURRENCY.GetBalance() >= 5 && empNotBought)
{
PlayerPrefs.SetInt("Emp Available", 1);
PlayerPrefs.Save();
empFilled = true;
StoreInventory.TakeItem(StoreAssets.TOKEN_CURRENCY.ItemId, 5);
}
}
else if (upgrade == 3)
{
bool immNotBought = PlayerPrefs.GetInt("Imm Available", 0) == 0;
if (StoreAssets.TOKEN_CURRENCY.GetBalance() >= 10 && immNotBought)
{
PlayerPrefs.SetInt("Imm Available", 1);
PlayerPrefs.Save();
immFilled = true;
StoreInventory.TakeItem(StoreAssets.TOKEN_CURRENCY.ItemId, 10);
}
}
else if (upgrade == 4)
{
bool multNotBought = PlayerPrefs.GetInt("Mult Available", 0) == 0;
if (StoreAssets.TOKEN_CURRENCY.GetBalance() >= 15 && multNotBought)
{
PlayerPrefs.SetInt("Mult Available", 1);
PlayerPrefs.Save();
multFilled = true;
StoreInventory.TakeItem(StoreAssets.TOKEN_CURRENCY.ItemId, 15);
}
}
Token.updateTokens (tokens);
}
}
8/26/15
I have now created both a google group and a google community for testing this app. I added the email for my other android device to the both of these and I used the link provided to download the app. Doing all of this still resulted in the same error as before.
8/27/15
I just noticed that my credit card on my merchant account had expired. One of the articles I read mentioned having issues like this if there were issues with the merchant account. I have updated the information and now I have to wait the deposit they will put in my account to make sure it is working. Once that is done I will update whether or not this fixed my current problem.
8/31/15
After finally verifying my merchant account on Google Play, I still seem to have the same problem. Fixing my merchant account did not change anything that I couldn't tell.
I just updated my post to include my whole StoreAssets.cs script and what I use to make purchases and consume items when a player uses them. I added this since I have no idea what else the issue could be.
9/7/15
Still no luck so far. Issue persists in android. The editor itself makes test purchases but purchases cannot be make from an android device without getting the same error as listed above.
9/9/15
Just as a quick update, I have tried building the project without the development build selected in the build settings and I send the link to all of the people in my Google community in order to give it a shot. Everyone still has the same error as my testing device does.
9/11/15
After trying a few things that Tony pointed out, I have noticed that the onBillingSupported() function is not called when I use this: StoreEvents.OnBillingSupported += onBillingSupported; I'm not sure why just yet.
9/12/15
After going through the tutorial on the soomla site, I have done everything it said except starting the Iab in the background and the fraud protection since they aren't required. the onBillingSupported method is still not called and I am still getting the same error as before on android devices.
9/12/15
I just removed everything for the Soomla plugin and imported the newest version and followed the instructions again and I still get the same error.
9/16/15
Really no idea what I am missing here. After removing all of the Soomla plugin and then adding it again and still getting the same error after multiple tries. I have followed everything as the tutorial says and I have all of the code above.
I have never had the problem you describe. I created a private Google+ community though, and added the community as testers. Shifted my App to Beta. And invited people to my private community where there was a link to download the app and test it. It was easy.
The second point, is your code above. You are fetching 4 goods and 3 currency packs but the code does not reflect that. Maybe you you only pasted half the class.
Finally, see if this thread will help: http://answers.soom.la/t/solved-some-clarification-about-iab-testing/2067/8
By the way, SOOMLA have a dedicated site answers.soom.la for SOOMLA related issues.
Did you try buying goods from another device?
I have had this issue before, but do not recall how I fixed it.
From what I remember when it failed for me, it was working on the different co-worker's device.
Try testing it on a different device.
also, do you have multiple google accounts on your device?
I remember that one of the things that I tried was removing all google account from my device and just left my main account registered. Unfortunately, I don't remember if that worked, but I hope it will help you.
if you find out how to fix it please post an update here. good luck
In my case, I didn't realize that what I was using for my item ID and my product ID were mixed up. The item ID is just to identify the item within soomla, the product ID is the actual I'd you,set in google play.
From the brief discussion in the comments it sounds like you may not have everything implemented.
Check out this link:
http://know.soom.la/unity/store/store_gettingstarted/
In the Getting Started section it states..
Create your own implementation of IStoreAssets in order to describe your game's specific assets.
Initialize SoomlaStore with the class you just created:
SoomlaStore.Initialize(new YourStoreAssetsImplementation());
Initialize SoomlaStore in the Start function of MonoBehaviour and NOT
in the Awake function. SOOMLA has its own MonoBehaviour and it needs
to be "Awakened" before you initialize.
Initialize SoomlaStore ONLY ONCE when your application loads.
The initialization is confirmed on this page as well.
http://know.soom.la/unity/store/store_istoreassets/
This says it is not mandatory but looks helpful
If you have your own storefront implemented inside your game, it's
recommended that you open the IAB Service in the background when the
store opens and close it when the store is closed.
// Start Iab Service SoomlaStore.StartIabServiceInBg();
// Stop Iab Service SoomlaStore.StopIabServiceInBg();
This is not mandatory, your game will work without this, but we do recommend it
because it enhances performance. The idea here is to preemptively
start the in-app billing setup process with Google's (or Amazon's)
servers.
You could try adding logging to the initialize event to make sure it is initializing. Here is a list of events you can try logging from..
http://know.soom.la/unity/store/store_events/
NOTE: One thing you need to notice is that if you want to listen to
OnSoomlaStoreInitialized event you have to set up the listener before
you initialize SoomlaStore. So you'll need to do:
StoreEvents.OnSoomlaStoreInitialized += onSoomlaStoreInitialized;
before
Soomla.SoomlaStore.Initialize(new Soomla.Example.MuffinRushAssets());
You can also setup the OnBillingSetup event with some logging to make sure it is initializing your billing correctly.
StoreEvents.OnBillingSupported += onBillingSupported;
public void onBillingSupported() {
// ... your game specific implementation here ... }

Handle a function taking a lot of time Threading

I have a function which is taking a lot of time to execute in a web application.
I have tested this with a profiler and by my logging.
I have other functions running in the same pageload.
What is a best way to display the rest of the values from those functions and keep this function in a thread and display it in a label when it finishes?
This function is used to get events in application which takes time.
private void getEventErrors()
{
EventLog eventLog = new EventLog("Application", ".");
getEvents(eventLog.Entries);
}
private void getEvents(EventLogEntryCollection eventLogEntryCollection)
{
int errorEvents = 0;
foreach (EventLogEntry logEntry in eventLogEntryCollection)
{
if (logEntry.Source.Equals("XYZ"))
{
DateTime variable = Convert.ToDateTime(logEntry.TimeWritten);
long eventTimeTicks = (variable.Ticks);
long eventTimeUTC = (eventTimeTicks - 621355968000000000) / 10000000;
long presentDayTicks = DateTime.Now.Ticks;
long daysBackSeconds = ((presentDayTicks - 864000000000) - 621355968000000000) / 10000000;
if (eventTimeUTC > daysBackSeconds)
{
if (logEntry.EntryType.ToString() == "Error")
{
errorEvents = errorEvents + 1;
}
}
}
}
btn_Link_Event_Errors_Val.Text = errorEvents.ToString(GUIUtility.TWO_DECIMAL_PT_FORMAT);
if (errorEvents == 0)
{
lbl_EventErrorColor.Attributes.Clear();
lbl_EventErrorColor.Attributes.Add("class", "green");
}
else
{
lbl_EventErrorColor.Attributes.Clear();
lbl_EventErrorColor.Attributes.Add("class", "red");
}
}
I have 3 functions in the pageload event, two to get the values from the DB and the other one is shown above.
Should both these functions be service calls?
What i wanted was, the page should load fast and if there is a function taking a lot of time it should run in the background and display when done and in the process if the user want to navigate to a new page it should kill it and move on.
If you have a function that is running in a separate thread in ASP.NET, you may want to consider moving it to a service. There are many reason for this
See this answer (one of many on SO) for why running long running tasks in ASP.NET is not always a good idea.
One option for the service is to use WCF. You can get started here. Your service could implement a method, say GetEvents() which you could use to pull your events. That way you won't tie up your page waiting for this process to complete (using AJAX of course). Also, this allows you to change your implementation of GetEvents() without touching your code on your website.

Categories