Jump to content
shadowayex

C++

Recommended Posts

Basically, the client I'm building is like a "browser", right? The "browser" needs to connect to the server application and have the server application do everything, just like building a website. Am I right?
YES. That's precisely the thing I've been trying to say. Basically, building a MMO client is like building a browser. The same security considerations you have with client side scripting apply to this as well.
If so, is it possible to have my client connect to an existing WAMP installation on a server I already have and create a new folder in that to hold all of the files needed to run the game, then have the client communicate with my server exactly like my website testers use their browsers to connect and communicate with my website files?
Yes, but it's the "A" in WAMP that worries me. Apache is an HTTP server. As I said, you can use HTTP to send and receive data to and from the server, but this will really slow down the game. HTTP is (in it's core) plain text traveling on TCP packets. The TCP packets travel completely from the client to the server (the HTTP request) and then the server, after receiving ALL packets sends back another set of TCP packets (the HTTP response) to the client.It would be A LOT more efficient if you could send a few TCP packets to the server and receive a few TCP packets at the same time.Think of it as asyncronous PHP (a non-existing concept, but it would really help if you can imagine it) - while the PHP receives the first $_POST variable, it checks if it's valid and returns an error if it's invalid. This can all happen before the second $_POST variable arrives for PHP to validate. And please don't confuse this scenario with AJAX. What AJAX does is to send another separate HTTP request just for the single variable. And what I'm talking about is breaking a single HTTP request/response cycle.

Share this post


Link to post
Share on other sites

I see what you mean. My understanding of that is limited, but I know enough to understand that what you are telling me is Apache will take everything at one, and send everything back at once, thus making it a horrible gaming experience. Instead I need to use something that will go bit by bit, thus saving memory and whatnot.That being said, and my breakthrough with knowing exactly what role the client plays now, I think I can do this a lot easier.Do you know of any application I can use that will work easily like WAMP, but will not cause the problem Apache would? I know it would be better for me to download each piece separately (like instead of WAMP, I should install Apache, then PHP, then MySQL, and so on), but for now, I want something quick and easy until I actually do a public release. Then when that happens, I'll do the proper installation and everything.But for now, I kind of want to lay this out, just to make sure that understand this correctly. After I build the client, everything else is basically like building a website. Whatever I use server-side (C++, PHP, etc.) would act like what PHP does in my websites. The OpenGL would be like what the HTML/CSS does in my websites. And MySQL of course will do exactly the same thing as well. If that's the case, my challenge will lie more in building the client than anything, since I've never done anything close to that before.

Share this post


Link to post
Share on other sites

There's a danger with thinking about your application using a web site model, they aren't really the same thing. In fact, they are fundamentally different. With a web server, you're using HTTP and HTTP is a stateless protocol. Every time you request a page from the server you're starting a brand new process, and the server handles your response and then closes the connection. A game like what you want to make needs to be stateful, not stateless. The connection between the clients and the server needs to stay open. An FTP model would fit more closely than an HTTP model. With FTP, your FTP client connects to the server on port 21. So the server is sitting there running, not doing anything except listening for connections on port 21. When a client connects, the client and server authenticate with each other and the client can start sending commands to the server (e.g. to create a folder, upload a file, etc). When the client starts downloading or uploading a file, a new connection is opened, it no longer uses 21. Port 21 is only for FTP control commands, for FTP data a new connection is opened on a new port to keep the command port open for other clients. When the session ends, then the port closes and the server ends the connection to the client.So you're going to be building 2 parts. One part is the server application, which doesn't include any graphics or anything like that. The server is a program that opens up a port (use a high port number, higher than 10000) and listens on it for the clients to connect. The clients are programmed to contact your central game server on the specific port number. Once the connection is made, then the server can open a new connection for the client to keep 2-way communication going while the server is still listening for other clients to connect. The client-server connection is what all of your game data is going across. The game data that needs to be transferred are things like the position of the player, what they're doing, health etc. Just the basic data. The client application is doing most of the game logic, like figuring out if the player successfully hit something or whatever, and rendering the graphics. The client just sends the server updates for what is happening with the player, and the server is sending back updates for what other players and things are doing. If it's a multiplayer game then the server also needs to control the enemy AI so that all clients see the enemies doing the same thing. If it's not multiplayer then the clients can do the enemy AI.Instead of starting with a game, start with something simple like a chat application, just two programs that connect to each other and send data back and forth. That will help you understand the data flow and how to listen for and set up connections. You'll be using the C++ socket library for the connections, you open a socket on a certain port and send data or listen for it.The main reason this isn't like a website is because with a web site, if there's no one on your site then your PHP scripts are not running. They only get executed when someone connects. The C++ server will keep running until either it crashes or you stop it. It just sits there in a loop waiting for input and sleeping. It's important that you have any program that loops periodically sleep for a few milliseconds or so so that the other applications trying to run get time with the CPU. If your program sits in a while loop and never sleeps then it will hog the server and other things won't be able to do their work, even if your server is just sitting there waiting for connections. When your program sleeps then the control gets transferred back to the CPU and the OS task scheduler can schedule the next program to do its thing. Your computer only has 1 CPU (maybe more today), and you might have 50 programs running. Those programs don't all run at the same time, your processor can only run one instruction at a time, so your OS has a task scheduler that is responsible for switching the current running process among all the applications trying to get CPU time to make sure that each application is able to do its work. So your program needs to periodically sleep so that the CPU will take over and give the next several CPU slots to other programs so that your server computer stays responsive. You don't want one program taking up all the resources.The main loop of your program will do things like checking to see if a client has connected, checking for new messages from clients, and sending updates to the clients. Each one time through the loop it will do those things. So your server just sits there looping waiting for things to happen and updating whoever is already connected. Your clients will open a connection and connect, and will show the graphical interface to the user with menus and things, and will render all of the game graphics. When updates come in from the server the client will update the objects on the screen. Your clients also sit in a loop, but the main loop for the clients mostly involves rendering the graphics. Each time through the loop results in 1 frame of animation. If you're running a game that's going at 50 frames per second, it's taking that program about 1/50th of a second to run through its main loop one time. The time to send and receive data with the server is going to be very small compared to the time required for the client to draw the scene.Notice that I've gotten this far and haven't even mentioned a database yet. You sound like you're focusing too much on the database, in all of my years at college we never made a C++ application that used a database, and I don't think I've ever downloaded a program that uses a database the same way a web server does. Your clients won't use a database at all, all storage on the client machines should be done in files. You'll want to look into file handling, but you can save your data in a big data structure and write the entire data structure to a file, then read it from the file and have all your data again. A process called serialization takes an abstract data structure and converts it to a string of binary data that you can save in a file. Unserializing takes the data and turns it back into the data structure that it started out as. You'll eventually want to set up several different classes and objects for your program to use, you might have a player class, enemy class, map class, item class, spell class, weapon class, inventory class, etc. Each class will contain the algorithms and data for managing that object, like a player class will have a method to move the player, a map class will have a method to load a map, etc. These objects are what you'll be serializing and saving in the files on the client side.On the server, you can and probably should use a database to store the global game data. A database will be faster than files because you'll have a connection open to the database the entire time, and databases have built-in features to handle things like multiple updates coming in all at once. You would have to manage those things yourself with files, so for the server a database is probably a better fit. You don't need a database for the clients though, and shouldn't use one. You don't want to force players to set up a SQL server on their computer in order to play your game.Also, you're going to get much, much better performance if you use C++ instead of PHP. I've never heard of someone implementing a server in PHP, there are better tools available.

Share this post


Link to post
Share on other sites

Ah, very informative. So first and foremost, I need to learn how to get a client to connect to a server, and furthermore, communicate with other clients. So a chat room would be the perfect thing to use for that.But even before that, I still need to set the server as a "server" in the first place. I have to learn how to make a client send something to the server, and receive a response back. Which means, I need to have a C++ code in the client sending a message to a C++ code on the server itself, and have the server code send a response back to make sure I've got a connection. From there, I can change the code to direct the message to all clients (or maybe even just a certain one, in the case of IM) and have the server wait for a message back, then send that response where it needs to go. Right?

Share this post


Link to post
Share on other sites

More or less. The server will maintain an open connection with each client, it's not like HTTP where you make a connection, get a response, and close. The connection stays open and either the server or client can send messages to each other at any time. The clients don't connect to each other though, that would be peer to peer, in a client/server model all of the clients only connect to the server and the server is responsible for updating each client. So in a chat application, the server would keep a database of the current chat messages and would send the messages to each client to keep them all updated. The clients would only send their messages to the server, they wouldn't send them to the other clients directly.

Share this post


Link to post
Share on other sites

Alright. I get it. The only problem is, how do I make it so the server will maintain a connection with the clients and whatnot. No idea how to do that.

Share this post


Link to post
Share on other sites

The connection will stay open until you explicitly close it (or something fails). Like I said, this isn't like HTTP. It's been quite a while since I've done any networking stuff with C++, but you will probably be using sockets. The server will open a socket on a certain port and wait for data to come in on that socket, and handle it when it does, and the client will open a socket and connect to the server on the same port. Either the client or the server can close the socket and the connection will end. If you're thinking that something like opening a connection between two programs is pretty common and there should be a lot of information about it, you're right.http://www.google.com/search?client=opera&...-8&oe=utf-8

Share this post


Link to post
Share on other sites

Ok, so two new questions:1) Do I have to download anything for this? Because a site I went to told me to download something, and I just want to make sure it's legit.2) How do I make the client connect? Is there a script that I have to write that says "Connect to <insert IP here> on <insert port here>" and then it's connected? That seems too simple. And even if that's the case, how do I route to the folder with the files in it? Please try to give me a break here, as I've never done anything like connecting to a server before. I downloaded WAMP and everything else was done for me, I just had to put the files in the www folder. I know nothing after that. Even when I did the PHP connect, it was just to localhost so yeah. Brain dead here, bear with my ignorance please.

Share this post


Link to post
Share on other sites

You might want to try to install the WAMP components separately then. Here's a good tutorial for that. Do it following the instructions, and when you see everything working, go back and analyze everything you have done. That is, WHY you had to do the things you did, like "Why did I had to create the line 'AddType application/x-httpd-php .php .php5'? What did that do? Is there a way without it and if not - why not?". And don't bother asking us... that's the type of questions you need to figure out on your own to understand what's going on. Feel free to look into the manuals though.(Apache, PHP, MySQL)Then uninstall and remove everything and try to do it again, this time without the tutorial. Ideally, do it on another clean computer. If you get everything up and running from the first time and understand how you did it, you're set.As for your questions:1. Whatever it is, if there isn't a price tag, it's probably legit. It's more likely that you get a virus on your PC than police at your home. What exactly are we talking about anyway?2. Pretty much there is. With socket_connect() and the sokect_create() functions. That's PHP, but they represent the BSD C equivalents. In other words, if your program is compiled in BSD, it will be able to access those functions. Your client however will not be based on BSD (it will be on Windows), so that part is probably not helpful.... (searching "sockets Windows")... ah, Windows sockets, of course, and with a tutorial even.With a risk of causing you another headache, I must tell you you don't need to search for a folder, as this is not how it works. The program listens for input on a certain port and that's all. On the server, you set one executable that will listen on one port and that's all. Nothing more and nothing less.So how does Apache work then you ask? When you ask for "http://localhost/folder/file.php", what you really get is a connection to "localhost" on port "80". The HTTP request (the plain text which Apache receives) starts with

GET /folder/file.php HTTP/1.1

And having that information, Apache finds the proper file for you, interprets it, and sends it's output as the HTTP response. Check out Fiddler (from my signature) if you don't get it and/or want to know more.I can see why you're brain dead here though. I know where all pieces fit into this puzzle, and I have some (small) experience in C++, and yet even I get a slight headache when I start thinking about it, so I can understand you feel 10 times worse than that when not understand where some of the pieces go. There was a Dilbert comic about this. An employee says "Oh my god! I actually start to undestand the stuff we are talking about at this meeting!", his head literally blows up and Dilbert says something like "They come and go faster each day" :) .

Share this post


Link to post
Share on other sites
2) How do I make the client connect? Is there a script that I have to write that says "Connect to <insert IP here> on <insert port here>" and then it's connected? That seems too simple. And even if that's the case, how do I route to the folder with the files in it?
To add to what Boen said, there aren't any scripts, and there aren't any folders or files, just 2 programs communicating. When your client connects it's not looking for a script to run, once it's connected it just sends commands to your game server and your server updates the necessary info. For example, one of the things you might send is a new X,Y position for the player, or if they pick up an item you'll send a command to update their info with the new item. The server receives all the commands and responds however you want, updating the central database or sending updates out to the other clients etc. Or to start basic, the client would send a command like they want to join a game in progress, or start a new game, etc, and the server would set that up for them and send them the info they need to continue with whatever's next.So yeah, this is a pretty major thing. When I was in college I took a class called CSE 470 that was the intro computer graphics class, where my group of 3 people made a little space racing game with checkpoints that you fly through, a starry background with planets and things (only pictures), a cockpit for the ship that you can see in front of you, a game menu when you hit escape to change options or start a new game, soundtrack, etc. That class, intro to computer graphics, is a 400-level computer science class, so before we took that class we had already taken 3 years of other computer science classes (and the OpenGL concepts were still pretty confusing). And we didn't even do multiplayer there, just the graphics. Here's the description page for CSE 470:http://sci.asu.edu/courses/descriptions.ph...139&maj=cseOnly taking computer science classes into account (and not the additional math classes), these other classes are required before you can start CSE 470 (ASU lists the textbooks on the course pages if you want an idea about what to read):CSE 310: Data Structures and AlgorithmsCSE 205: Object-Oriented Programming and Data StructuresCSE 100: Principles of Programming with C++This is why I told you earlier that you will probably want to become familiar with C++ in general before you try to do anything with graphics, there are a lot of things you need to understand if you're going to solve some of the problems that go with making an entire multiplayer game from scratch. I'm not trying to discourage you, but if you were thinking this was a months-long project, it's probably more like a years-long project. It would be a years-long project for me as well, with the knowledge I already have about C++ I would start with the networking code and getting a client and server set up that could send messages to each other. I would test that for a while before I moved on, so it would be months to set up the networking code and make sure that it gets tested in several environments (firewalls, dial-up, etc). Once I had some basic networking code that I was happy with then I would start making the rendering engine for the game, and that would involve a lot of reading and research about game engine design. You can also buy a game engine and use it, the engine that runs the Unreal games is available for licensing. The 2.x versions would probably be cheaper to license than Unreal Engine 3, but they don't put the licensing fees on their site so I would imagine that they would ask tens to hundreds of thousands for their engine and all the tools that they use to create the game and the objects in the world. Most game developers, in addition to making the game engine itself, also make the authoring tools that they use to create the maps, objects, etc. For example, when Half-Life was out Valve released a program they built called Worldcraft and then the Hammer Editor which they used to build all of their maps and compile the map for their engine. There was a separate program called Wally that was used to package all of your source images into texture files that you could use in the map. So not only did they build the engine, they also built the IDE to build the maps for the engine. When you buy the Unreal engine you get about 10 other tools, from the map making tool to a texture creation tool to an object building tool, etc.This all probably sounds a little daunting, but I'm just trying to make the point that if you think making a game sounds incredibly difficult and confusing, it's only because it is.If you want to just make a little game and not try to kill yourself, you might want to use a free game engine instead of making your own. When I was in CSE 470 there was one available called the WildTangent Web Driver that was a Java engine for making games that played in a browser. I'm not sure if that's still around or not, I know WildTangent was associated with adware at some point. But there should be some free engines that you can use. Don't expect anything mind-blowing from them, but they're free.You might also want to download something like the tools from Valve for making maps for the Source engine so you can at least get an idea about some of the things that go into mapmaking. Make a Half-Life 2 map of your house or something (my friends and I have had many fine battles in my old apartment, complete with furniture, working ceiling fans, TVs, computers, etc). Trying to create the engine without understanding how an engine works would be a bit difficult.

Share this post


Link to post
Share on other sites

@_@ Yay, lots of information. Now, to respond. I was sure this project was going to take a long time, and that's exactly why I chose it. It's something that my friend and I both want to create, in a field that both of use have a passion for, and what better way to learn than by learning what you need to use for a project you're passionate for? I wasn't expecting to come close to having graphics or anything for a year or two. And even when I started, I wasn't expecting to have it done for years to come. But I figured if I could learn how to build a client that connects to a server, from there I can experiment until I'm ready to move on. I think starting with a chat would be perfect, consider the game would include a chat anyways.So instead of thinking like I'm building a whole game, I want to look at it as I'm building a chat which can be implemented into a game. Sound better?For this project, I need to build a client that will connect to a server program that inserts and selects messages, and sends them back to the clients. Do you think that's too difficult for a beginner? (I hope that doesn't sound like I'm being a smart-alec, it's an honest question)So step one: write a client that will load a program that inserts text into a database.The server program (I would assume) would be running all the time, and is programmed to listen to port, let's say, 12345. When something comes in on port 12345, it will take that information and store it into the MySQL Database it's programmed to store it into.The client would be programmed to ask for a string, and then once the string is provided, send it to <insert server IP here>, through port 12345.After all that works, I would expand it to sending information back, but that's what I want to start with.Is there any specific things I need to download or anything to get this to work? Or would just writing the two programs work? Also, what functions would I use to translate what I've just explained into C++, more specifically sending the string. There's the documentation for the MySQL provided already, and I already know how to get the string and everything. I just don't know how to make the programs communicate.

Share this post


Link to post
Share on other sites

A chat application sounds more feasible, before that maybe just an application that simpy passes a message and nothing else (no database work, nothing). Just you type something on the client or the server and it shows up on the other one. I think you're still not understanding a few things about how it works but I don't think any amount of talking about it is going to be helpful, you just need to jump in and start doing things. For example, the client doesn't do anything with the database and the server doesn't need to know the client's IP (the C++ socket library should handle that). The server just sends something across the socket connection once established, the socket library manages where that connection actually goes. Also, in the case of a chat application the client wouldn't be asking for updates, the server would just send them whenever they come in. That's another difference with HTTP, with HTTP the client needs to ask the server for an update. With a socket the server can push an update to the client, the client doesn't need to ask because the connection is already open, the client just sits there waiting for data from the server and when it gets an update it handles it.So we could keep talking about this until we're both blue in the face, but some things just aren't going to make sense until you start doing it and seeing what's involved and what happens. So I would recommend starting with a socket tutorial and first just make your server that will open a connection and sit there listening.

Share this post


Link to post
Share on other sites

I haven't looked up socket tutorials yet, I'm just getting ready to. But I was wondering if there was some way I could convert variables from string to int. The reason I ask is I'm using an array to set things up right now, and the array type is string, but a couple values are actually integers. How can I convert the type so I can do operations with them? Also, if I wanted to set a variable equal to some text and another variable, is there a specific way to do it. For example, in PHP I would do this:

$var = 'This is a variable that includes this data (' . $othervar . ') from another variable.';

Understand what I'm asking?

Share this post


Link to post
Share on other sites

I was recently on an IT exam at the local university (I have 5.20 out of 6.00 btw), and on my practices before it, I asked the same in the cplusplus.com forums and there were two golden functions that came out of it. I later generalized them into the following two templates:

template <class T> string toString(T n) {	std::ostringstream result;	result << n;	return result.str();}template <class T> T fromString(string s) {	T result;	std::istringstream ss(s);	ss >> result;	if (!ss) throw std::invalid_argument("Unable to convert the string \"" + s + "\" to the requested type.");	return result;}

Using those two templates, you can easily do something like:

int othervar = 1;string var[2];var[0] = "a" + toString<int>(othervar);//var[0] is now string("a1")

or

string i="5";string e="6";int var = fromString<int>(i) + fromString<int>(e);//var is now int(11)

The beauty of these templates is that they can convert to and from any type coupled with a string. After all, except integers, you might need this sort of convertion for floats, booleans and others.The code works by using string streams. They work the same way as stdin and stdout with the difference that their contents comes from a string rather than from the environment as with the IO streams.From string streams, as with stdin you can extract a value to a variable that is in any type. Also, as with stdout, you can write any variable onto the stream.

Share this post


Link to post
Share on other sites

I have a battle script, very simple. I have a formula that calculates hit/miss percentages and compares it to a random number. I have a similar script twice, one for the player and one for the cpu. Each are supposed to generate a random number of their own, but they generate the same random number. Anyway to fix this? Just in case, here's a chunk of the code I'm working with:

            while(Choice2 != true) {                cout << "\nWould you like to attack?\n(Y,N): ";                cin >> choice2;                if(choice2 == "Y" || choice == "y" || choice == "N" || choice == "n") {                    Choice2 = true;                } else {                    Choice2 = false;                }            }            if(choice2 == "Y" || choice2 == "y") {                srand(time(NULL));                Rand1 = rand() % 100 + 1;                cout << "Rand1 " << Rand1 << "\n";                hit = floor(75 * (player2spd / player1spd));                hit = 100 - hit;                if(Rand1 >= hit) {                    damage = player2atk / player1def;                    damage = player2atk * damage;                    damage = ceil(damage);                    player1hp = player1hp - damage;                    if(player1hp < 1) {                        cout << "\nYou Won!";                        break;                    } else {                        cout << "\nYou attacked " << player1name << " for " << damage << " hp.";                        cout << "\n" << player1name << " has " << player1hp << " left.\n\n";                    }                } else {                    cout << "\nYou missed " << player1name << "\n\n";                }                srand(time(NULL));                Rand2 = rand() % 100 + 1;                cout << "Rand2 is " << Rand2 << "\n";                hit = floor(75 * (player1spd / player2spd));                hit = 100 - hit;                if(Rand2 >= hit) {                    damage = player1atk / player2def;                    damage = player1atk * damage;                    damage = ceil(damage);                    player2hp = player2hp - damage;                    if(player2hp < 1) {                        cout << "\nYou Lost!";                        break;                    } else {                        cout << "\n" << player1name << " attacked you for " << damage << " hp.";                        cout << "\nYou have " << player2hp << " left.\n\n";                    }                } else {                    cout << player1name << " missed you!\n\n";                }            }

Is there a reason for the error and a way to fix it?

Share this post


Link to post
Share on other sites

Random numbers aren't truly random, in any language. They have yet to find a reliable way to create a number that is truly random, all random number generators are based off something that is not random. Instead of seeding the second random number with the same thing that you seed the first one, seed the second one with something else (like the first number itself). If you seed the next number with the previous number then you'll pretty much be guaranteed to get a different number every time.As for the conversion, if you want to convert a single variable there are functions like atoi, strtol, strtod, etc.http://www.cplusplus.com/reference/clibrar...tdlib/atoi.htmlhttp://www.cplusplus.com/reference/clibrar...lib/strtol.html

Share this post


Link to post
Share on other sites

Hello, I've been plugging away slowly, but I haven't been able to do server communication stuff yet. I just installed ubuntu on my server, and I've been searching for a socket tutorial with no luck. I just get sites with people asking for the very same thing I'm asking. Frustrating.Anyways, does anyone know of any good tutorials?

Share this post


Link to post
Share on other sites

This has a few examples with a few types of socket classes:http://www.alhem.net/Sockets/tutorial/This looks like a good one also:http://www.linuxhowtos.org/C_C++/socket.htmMost of that is in C, but you can use the C code in a C++ program or it shouldn't be too bad to convert it to native C++.

Share this post


Link to post
Share on other sites

Thanks, I'll take a look.Also, kind of a sidebar, but I know that Ubuntu comes with a firewall, but should I get a better one? I looked around and most of what I've read says that there's not too many problems with spyware on Linux, but I want to be as safe as possible. I've installed Avast so far, and I was looking for a Linux equivalent to ZoneAlarm because I loved that firewall. But after reading around, I know there's not one, and I'm not sure if I even need to upgrade. If so, do you know anything good?

Share this post


Link to post
Share on other sites

Ok, I've got a question about the socket stuff. The socket function has me put localhost and the port number. How do I make it so it actually goes to the server from another computer? Would I put the computer's IP in place of localhost or what?

Share this post


Link to post
Share on other sites
Ok, I've got a question about the socket stuff. The socket function has me put localhost and the port number. How do I make it so it actually goes to the server from another computer? Would I put the computer's IP in place of localhost or what?
Yes.

Share this post


Link to post
Share on other sites

I've found everything on making Linux server programs and client programs, which is what I needed. But I also need to know how to make a Windows client program, which conveniently enough I can't find a single thing on. I just keep finding tutorials on making a Windows server program that always end in something like "Now try to have your client connect and you're done." >_< I'm getting extremely frustrated.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...