 Crypto Grounds here. Welcome back to another Unity idle game tutorial video. This is episode 39 and today we're going to be doing time cheap protection. All right. So this is kind of be based on our daily reward system. So if you haven't checked that out, make sure you do because it kind of runs on that reason is because we're going to be using our API or UTC time API in order to save our, our offline time rather than on our phones. Okay. So let's see. Let's just hop into our offline manager. Cause I think this is where I get, actually, no, it might be the daily reward manager, but we will need the offline manager open. So we'll just hop into that. Okay. So what we're going to do now is that we're going to create an async method. So basically we will be able to use the await command or not command, but term where we can pause the called method basically, which is really cool until we get an input. Okay. Or a result or a turn. Okay. So we're going to call this get or we're going to call this await get UTC time. Okay. So now we need to, okay. So we're going to be able to use this in here, but in order to do that, we need to also add a sync to our load offline productions. Okay. And this will also cause some issues where we're going to have to use this term in our main scripts, but I'll get to that later on. Like we go here. Actually, it shouldn't be an issue, right? Uh, I guess not. Never mind then. Ignore what I just said, but okay. So we're going to, okay. I see here, you know what? Let's actually make it return, uh, a time, a date time instead. So we're going to make this a public async date time. Okay. Is that possible? Let's see if we fix this. Okay. So we're going to make this into a task instead. So basically what a task is, is that we are creating a method on another thread that will do its thing. Okay. And we will return the type date time. Okay. So let's see. We need to grab our daily reward manager. I'm going to call this daily. The reason why is because we, we get this UTC time here. Okay. And I feel like I should do this. Actually, you know what? We're going to do this in here on its own because we're going to do this in a task as well. Okay. Um, yeah, we're just going to have this in here. Okay. And this is, this is annoying because this requires an enumerator and this is different. So I think we're just going to have to manually do a delay. I mean, that sounds really unprofessional, but the pretty much the most efficient way I can think of doing this. Okay. So let's grab our daily object, our daily reward manager. We're going to call it daily. Okay. And in here, we're going to call daily dot, uh, I think it's, yeah, get UTC time. Get UTC time. Okay. What's this? No, we don't need that. That's weird. Okay. So basically we're going to call this method now or this, uh, oh no, this is a start co-routine, right? So we're going to do start co-routine daily dot get UTC. Okay. And once we do that, uh, can we await start co-routine? No, we can't bummer. Okay. And then we're going to do, uh, task dot delay. And we want it, let's just say we want it to delay for a thousand or a thousand milliseconds. Okay. We're going to do await task delay, 1,000 milliseconds, which is one second. Okay. So it'll take one second to get this time, which I think is enough. Okay. Cause we can just do the same thing here. And then after that, so this, remember this pauses literally just stops it right here for a second. And then it continues. We're going to create a public date time, current date time. Uh, yeah. Current UTC date time. Okay. And then after that, we are going to set this equal to daily dot temp date time. Okay. And by then we should have our current date time. Okay. Now we can return. Actually, we don't need to create this variable. We can just return, return date, or daily dot dem, temp date time. There we go. Okay. So now we have our task here. We need to call this in here. Okay. So now what we can do here is replace this date time dot now with this method call. And then we got to add the await to term to it. So basically it will wait till this is done till we have an answer right here from a wait, get UTC time. Once we do it will set the variable current time to what is returned here and then continue to code. So that's the nice thing about the async, the asynchronous methods and using the wait term is that you can do fancy stuff like this. Okay. We're not done yet. So now we have, we can pretty much use this universally, I guess. Now we need to set this right here as well. Okay. And honestly, when we save our player, we can save it as no, we don't want to save it as UTC now. Okay, I keep thinking I want to do UTC now because it's like in the UTC. But what if our device is shifted another day? That's an issue, right? We want to actually get this time to. Okay. So let's create some methods here. We're going to create another async void. Yeah, I think this is going to be. Yeah, I think this has to be a wait. This is pretty much going to be the same thing here. Okay. Let's add tasks. Okay, which also if you can't access tasks, this will be system dot threading dot tasks. Okay. That is where tasks come from. And let's see. Now instead of starting a co routine, we can just call our offline method to instead, which we will do. We'll just add offline manager. Or initialize it, we'll call it offline. We'll declare it. Sorry, I can talk. And basically, we are going to do the same thing. Except we're going to return offline dot await, get UTC time. And we're not done because we have to add the await term to it. So basically, it will and the reason why we have to do this is because if we add the static term, which is where we would call in here, then we can't use offline, right? Okay. And actually, you know what, let's make this avoid instead, add a date time in here, because we don't want to return it because we won't be able to call this in the safe player. Okay, so we're going to call we're going to create a current UTC time. So this is really confusing. I understand if it is. And we're going to set current UTC time to await offline dot await, get UTC time. Boom. Okay. And then it will place a date time dot now in our safe player method with current date time. Oh, what's the what's the problem? Oh, we got to make the static. Okay. Now, can make that private. Okay, so now we need a way to call this. Okay. So what we'll do is this call this method before we save every time. So we'll go to our main scripts, our idle tutorial game. Okay. And we're going to go to the bottom where our save is. And I'm going to create a separate async void save method. Okay. And in here, we want to put this in here, put that in here. Okay, so we need to add since this is non static, we need to add a safe system game object, which I've already done earlier. I forgot to delete it because I messed up. But basically, you just type in public safe system, non static safe system, or whatever the name you want. Okay, so then you can use a non static method, such as this way, non static safe system dot wait, get UTC time. Done. Okay. Now, we want to we can add a wait to this note, we can't write void is not waitable. Okay. Oh, wait, what do we do? Oh, okay. So basically, what I did is that I turn this into a task. So then this is awaitable. Okay, because you can't await void methods. Apparently, I don't exactly know reason why. But if we make this a wait, you get UTC time or method into a task. Sorry, I'm like trying to find it right here. So if we make this into a task instead, it won't interfere with anything in here. It's still a sync, right? It's still in a sync method. It's just a different type of method. So then we can await it. So we will not save the player until we get this UTC time. And then we will call the save system player. So now where are we going to call this? We're going to call this in here. Okay. So the cool thing is that we can still call save in a non a sync method, because we're not I mean, we can do a wait save. But there's no points because I mean, we can just set this offline progress check to true and the save timer to zero. I mean, we don't need to wait for that. Otherwise, we could just make this a sync. But again, this is a void, we can't await a void. So we just got to make this a task. And see, or what's this? Oh yeah, we get import tasks. But again, this is just enough process we don't need to do. We can just call save normally as a normal method, like that. Okay. And now let's test it. Do we replace everything? I believe so. I hope this all made sense. Tasks are definitely an asynchronous methods are definitely a completely different beast. This is where my mistake was. Hopefully it doesn't mess anything up. We'll see though. But yeah, they're completely different beasts. And if you get confused with them, it's totally okay. I will eventually get to those in my crash course series once I get that started. All right, let's see. Okay, 42 seconds. So let's let's save this. We have we have a very negative number. Let's get rid of that. So those negatives aren't fun. There we go. So we're gonna, so we saved, let's see right here. Save. Okay, so we're gonna wait a few seconds. One, two, three, four, five, six, seven, eight, nine, 10. Yes, we got it. Yes. How do you think this is going to work? Awesome. Well, there you go. Anti-time cheat. So in review, basically what we did is that we grabbed, we made a task and a synchronous task type datetime where we can call our co routine and delay it by a second, which is totally okay. Because that's about how long it would take. And honestly, if the servers are down, which it won't because a lot of people rely on this. And if it does, then I guess we just don't get offline progress for a little bit. But in case that happens, then I don't know. Otherwise, we will just pause for a second while we get a result here. Okay. And then we return our template datetime, which is from daily reward, which we set right here. Okay. And then we set it to our current time. All right. And now we grab our offline time from making another async task, where we set current time equal to await offline, await get you to see time a lot of waits, which is this method right here. Okay. And so we're calling this twice, I think. Yeah, we're calling it twice. So we're getting we're using this for the current time as we're loading and the current time as we're setting or saving. So these are very, this is a very crucial method right here. So make sure you pay close attention. I hope you understood as I was explaining these. Okay. And we set our offline time to the current ECT time. And we create another async save method to await this process. And then we save the player once this is done. Alrighty, if you enjoyed this episode, make sure you smash the like button, subscribe to my channel and turn on those notifications. If you're new here, comment your suggestions and feedback and everything below. Send me some love, everything I really appreciate. And I will be sure to like and reply and heart all your comments as I can. Check out my Patreon. We are still two patrons away from getting the anti metro dimension series, which I'm really hyped about. Okay. And let's see, do I have anything else to talk about? Oh yeah, on my channel, there's, there's that poll still for my merch. So make sure you vote on that 50 votes and I will release it early. Okay. Anyways, I will see you in another video. Thanks for watching. Peace.