DanShadows .NET Turing Tutorial

.NET commands are commonly used to send information over the internet.
As shown in the Turing Examples section, there is a chat. This chat,
like all net programs, must have a server and a client. The server
which when open, must: (a) Connect new users (b) Get information from
clients already connected (c) Send information from each client to each
other client. The clients job is to send that information, then wait
for the server to send the rest of the information back. Here are the
.NET commands and a quick explanation of their purpose that I will
use in this tutorial.
netStream:=Net.WaitForConnection (port,ip)
(This waits for a user to connect on a given port, and saves the
IP address of the new user under 'ip', and saving the connection
under the variable netStream.)

if Net.LineAvailable (netStream) then
(This checks if a message is available from a netStream address,
and if it is, it will do what is set in the 'if' statement.)

put : netStream, text
(This will send the information stored in the variable 'text' over
the set netStream.)

netStream:=Net.OpenConnection(ip,port)
(This is used by the client to open a connection to the server at a given ip and port.)
If any of this doesnt make sense to you, its ok, dont panic!
Just to give you a quick feel for how sending information over the
net goes, ill give a quick commented example on how its done.
|------------------------------------------------------------|
|                     Server Code                            |
|------------------------------------------------------------|
|%% Sets the initial port as a constant integer value : 5535 |
|const port : int := 5535                                    |
|var netStream:int                                           |
|var ip,test:string                                          |
|%% Shows the programmer that the server is awaiting for     |
|%% a connection                                             |
|put "Awaiting initial connection..."                        |
|%% Waits for a connection, and saving all information in the| 
|%% variable netStream                                       |
|netStream:= Net.WaitForConnection (port,ip)                 |
|%% Gets all the text from the client under the var name test|
|get : netStream, test:*                                     |
|%% Displays the text sent from client                       |
|put "Text from Client: ",test                               |
|%% Gets text from server                                    |
|put "Enter text to send back: "..                           |
|get test:*                                                  |
|%% Sends the text in variable 'test' to client              |
|put : netStream,test                                        |
|------------------------------------------------------------|
|------------------------------------------------------------|
|                     Client Code                            |
|------------------------------------------------------------|
|%% Sets the initial port as a constant integer value : 5535 |
|const port : int := 5535                                    |
|var netStream:int                                           |
|var ip,test:string                                          |
|%% Requests IP address of the server from the client        |
|put "Enter IP address of server: "..                        |
|get ip                                                      |
|%% Shows the user that the client is trying to connect to   |
|%% the server                                               |
|put "Attempting connection..."                              |
|%% Opens a connection, and saves all information in the     | 
|%% variable netStream                                       |
|netStream := Net.OpenConnection (ip, port)                  |
|    if netStream < 0 then                                   |
|        put "Could not connect to server. Sorry!"           |
|        break                                               |
|    else                                                    |
|        put "Connection Astablished."                       |
|        delay (2000)                                        |
|    end if                                                  |
|%% Gets text to send to server                              |
|put "Enter text to send to server: "..                           |
|get test:*                                                  |
|%% Sends the text in variable 'test' to server              |
|put : netStream,test                                        |
|%% Gets all the text from the server under the var name test|
|loop                                                        |
|    if Net.LineAvailable(netStream) then                    |
|       get : netStream, test:*                              |
|       exit                                                 |
|    end if                                                  |
|end loop                                                    |
|%% Displays the text receieved from server                  |
|put "Text from Server: ",test                               |
|------------------------------------------------------------|
Well, for the purpose of this tutorial, I will create a multi-user
chat interface, then disect it so you can understand what everything
does. First, we shall program the server, lets declare some variables:
|-----------------------------------------------------------------------|
|                     Server Code                                       |
|              200 Lines w/out Comments                                 |
|-----------------------------------------------------------------------|
%% Sets the initial port as a constant integer value : 5535
const port : int := 5535
%% Creates a record called 'person', which will contain their netStream
%% address, their ip, name, and the message they might send.
type person :
    record
	netStream : int
	ip, name, msg : string
    end record
%% Creates an array called 'user' of 10 of the record 'person'. This
%% will allow 10 people to connect successfully.
var user : array 1 .. 10 of person
%% This sets the initial values of each user to a null state.
for i : 1 .. 10
    user (i).netStream := 0
    user (i).ip := ""
    user (i).name := "null"
    user (i).msg := ""
end for
%% Declares the 'key' variable to use in the getch command
var key : string (1) := "~"
%% Declares some miscellanious variables to hold text
var temp, command, input : string := ""
%% usersOnline will track how many users are online, and this will
%% determine which port the server will wait for a connection on.
%% num is a miscellanious variable to hold an integer.
var usersOnline, num : int := 1
%% Shows the programmer that the server is awaiting the first connection
put "Awaiting initial connection..."
%% Waits for a connection, and saving all information in the first spot
%% in the 'user' array.
user (1).netStream := Net.WaitForConnection (port + usersOnline, user (1).ip)
%% Updates the 'usersOnline' variable showing that there is one person connected
usersOnline += 1
%% This process will autoconnect new users and auto-update the usersOnline variable
%% as long as there are less or equal to 15 users online
process connectNewClients
    loop
	if usersOnline <= 15 then
	    user (usersOnline).netStream := Net.WaitForConnection (port + usersOnline, user (usersOnline).ip)
	    usersOnline += 1
	end if
    end loop
end connectNewClients
%% Forks the 'connectNewClients' process so it will autoconnect new users
%% while in the loop
fork connectNewClients
%% Starts the loop
loop
    %% setscreen and View.Update will eliminate flickering
    setscreen ("offscreenonly")
    View.Update
    %% Clears the screen, and draws a black background
    cls
    drawfillbox (0, 0, maxx, maxy, 16)
    %% Sets the colorback to black, and the text to red
    colorback (16)
    color (12)
    %% Creates a delay so the program doesnt go too fast and overload
    delay (10)
    %% Shows that it is the server, displays which port it is awaiting
    %% the next conenction on, and the amount of users online
    locate (1, 1)
    put "Chat [Server] - By DanShadow"
    color (10)
    put "Awaiting Connection on Port: " ..
    color (0)
    put port + usersOnline
    color (10)
    put "Users Online: " ..
    color (0)
    put usersOnline - 1
    put ""
    %% Displays the IP address, and name of each user online
    for i : 1 .. usersOnline - 1
	color (12)
	put "User ", i, "> " ..
	color (10)
	put "[IP:" ..
	color (0)
	put user (i).ip, "" ..
	color (10)
	put "] | [Name: " ..
	color (0)
	put user (i).name, "" ..
	color (10)
	put "]"
	%% Checks if the netStream of user 'i' is connected
	if user (i).netStream > 0 then
	    %% If info is being sent by user 'i' then
	    if Net.LineAvailable (user (i).netStream) then
		%% Gets user 'i's update name 
		get : user (i).netStream, temp : *
		user (i).name := temp
		%% Gets user 'i's text he/she has sent
		get : user (i).netStream, temp : *
		user (i).msg := temp
		%% If the message isnt equal to nothing then
		if temp not= "" and temp not= "null" then
		    %% Sends that message to all users
		    for j : 1 .. (usersOnline - 1)
			put : user (j).netStream, user (i).msg
		    end for
		end if
	    end if
	end if
    end for

    %% If the user using the server presses a key, it enables the command
    %% menu, where the server can use special adminary abilities
    if hasch then
	getch (key)
	%% If the user of the server presses 'ENTER', it submits the
	%% command variable for processing to do special abilities
	if key = (KEY_ENTER) then
	    %% If the server decides to '@boot' somebody...
	    if command = "@boot" then
		locate (3, 30)
		%% This gets the ->USER NUMBER<- and boots him
		%% I didnt bother using strintok, so dont be stupid!
		%% If you type in a string, you'll crash the server!
		get command
		temp := "*** YOU HAVE BEEN BOOTED FROM THE SERVER ***"
		%% Tells the client he has been booted
		put : user (strint (command)).netStream, temp
		%% Closes the connection with that client
		Net.CloseConnection (user (strint (command)).netStream)
		user (strint (command)).netStream := 0
		%% Displays that the user is booted from the server
		user (strint (command)).name += " [BOOTED FROM SERVER]"
	    %% Slaps the client...same stuff as above            
	    elsif command = "@slap" then
		locate (3, 30)
		get command
		temp := "*** You have been slapped by the Server! ***"
		put : user (strint (command)).netStream, temp
	    %% Devours the clients soul
	    elsif command = "@devour" then
		locate (3, 30)
		get command
		temp := "*** The Server Devours Your Soul! ***"
		put : user (strint (command)).netStream, temp
	    %% Warns a client
	    elsif command = "@warn" then
		locate (3, 30)
		get command
		temp := "*** You have recieved a WARNING from the Server! ***"
		put : user (strint (command)).netStream, temp
	    end if
	    command := ""
	else
	    %% Adds the key being pressed to the string 'command'
	    command += key
	end if
    end if
    %% Displays the command being entered by the server
    locate (3, 20)
    color (10)
    put "Command: " ..
    color (0)
    put command
end loop
|-----------------------------------------------------------------------|
|                     End Server Code                                   |
|-----------------------------------------------------------------------|

|-----------------------------------------------------------------------|
|                     Client Code                                       |
|              120 Lines w/out Comments                                 |
|-----------------------------------------------------------------------|
%% Declares and initiated port as the integer value 5535
const port : int := 5535
%% Opens an array to store the messages said. (Up to 5000)
var chatMsg : array 1 .. 5000 of string
%% msgNum tracks how many messages chatMsg has stored
var msgNum : int := 1
%% Sets all of chatMsg equal to null
for i : 1 .. 5000
    chatMsg (i) := ""
end for
%% Declares the record person which hold the msg he typed, his name
%% his IP, and the netStream he will use to send info the the server
type person :
    record
	netStream : int
	ip, name, msg : string
    end record
%% Declares the amount of usersOnline, and a miscellanious variabled 
%% called num
var usersOnline, num : int := 1
%% Declares that there will be 15 users
var user : array 1 .. 15 of person
%% Sets the user info to null
for i : 1 .. 15
    user (i).netStream := 0
    user (i).ip := ""
    user (i).name := "null"
    user (i).msg := ""
end for
%% Autosets the IP of the server. (This is mine, but I dont have
%% internet, so change this to your IP.)
user (1).ip := "169.254.163.54"
var counter : int := 15
%% Draws a black background
drawfillbox (0, 0, maxx, maxy, 16)
%% Sets text colorback to black, and the text to red
color (12)
colorback (16)
%% Displays that this is the client
put "Chat [Client] : By DanShadow"
put ""
%% Sets text color to white
color (0)
%% Displays that the client is connecting to the server
put "Please wait, Connecting..."
color (10)
%% ALL this code below, just checks from ports 5550 down to 5535
%% going backwards, so it will autoconnect on the first available
%% port that the server will be waiting on. If none of these ports
%% are open, it will display that the client couldnt connect.
loop
    View.Update
    user (1).netStream := Net.OpenConnection (user (1).ip, port + counter)
    if user (1).netStream < 0 then
    else
	put "Connection Astablished."
	delay (2000)
	exit
    end if
    counter -= 1
    if counter = -1 then
	put "Could not connect to server."
	View.Update
	delay (2000)
	break
    end if
    delay (1)
    locate (4, 1)
    num := round (counter * 5)
    put "Connecting: ", 100 - num, "%"
end loop
%% Declares the variable 'key' to use in the getch command
var key : string (1) := "~"
%% Creates miscellanious text variables
var name, textInput, temp, input : string := ""
%% Gets the users name
put "Enter your name: " ..
get name : *
%% Makes the Second chat message as a temporary welcome message
chatMsg (2) := "Welcome to Chat " + name + ", brought to you by DanShadow"
%% Clears screen, then displays its the chat, by me.
cls
put "Chat : By DanShadow"
put ""
temp := name
%% Sends the server your name, and the message that you have connected
put : user (1).netStream, temp
temp := "[I] " + name + " has connected."
delay (50)
put : user (1).netStream, temp
%% Starts the chat loop
loop
    %% setscreen and View.Update eliminate flickering
    setscreen ("offscreenonly")
    View.Update
    %% If the server is sending information to the client
    if Net.LineAvailable (user (1).netStream) then
	%% Get the info being sent, save it in variable 'temp'
	get : user (1).netStream, temp : *
	%% Add it to the array of messages
	chatMsg (msgNum) := temp
	%% Update messages in chatMsg
	msgNum += 1
    end if
    %% Declares 'key' as an unusable key '~'
    locate (1, 1)
    key := "~"
    %% If the user presses a button, it saves it under var 'key'
    if hasch then
	getch (key)
    end if
    delay (5)
    %% If the user presses 'ESCAPE', the program exits
    if key = (KEY_ESC) then
	exit
    %% If the users presses 'BACKSPACE' then the users input
    %% variable is updated to its original length-1
    elsif ord (key) = 8 then
	input := ""
	for i : 1 .. length (textInput)
	    if i < length (textInput) then
		input += textInput (i)
	    end if
	end for
	textInput := input
    %% If the user presses 'ENTER', it sends his name and message
    %% to the server
    elsif key = (KEY_ENTER) then
	temp := name
	put : user (1).netStream, temp
	delay (50)
	temp := textInput
	put : user (1).netStream, name + ": " + temp
	textInput := ""
    else
	%% Makes the users message equal to null
	user (1).msg := "null"
	%% if the ord of the variable 'key' is 
	%% upper/lower case of the alphabet, is a numeral,
	%% or a few other allowed keys, it adds it to the
	%% user input variable textInput
	if ord (key) >= 32 and ord (key) <= 122 then
	    if key not= "~" then
		textInput += key
	    end if
	end if
    end if
    %% Draws a black box, therefore clearing the screen
    drawfillbox (0, 0, maxx, maxy, 16)
    locate (1, 1)
    %% Resets colorback as black, and text as red
    color (12)
    colorback (16)
    %% Displays that this is the client
    put "Chat [Client]: By DanShadow"
    put ""
    color (10)
    %% Displays all the messages received so far
    for i : 1 .. msgNum
	put chatMsg (i)
    end for
    put ""
    color (12)
    %% Displays the input currently typed in by the user
    put "Input: " ..
    color (0)
    put textInput
end loop
|-----------------------------------------------------------------------|
|                     End Client Code                                   |
|-----------------------------------------------------------------------|


Well, that was a very long lot of code! TAKE A BREAK! Think about what
you have read so far. I hope you are at least grasping the basic concepts
of .NET commands so far though. If you aren't...:
Start Re-reading the code from the top to bottom
Start creating mini-programs for yourself to make sure your getting
a feel for what is going on.
And if you still aren't understanding it..ask me, DanShadow!
[Do the above steps before though, and you probably wont need
to ask me!]
Now, seeing as Turing .NET commands are so damn slow, you may want
to go on to a new language, and by all means do! If you still havent
mastered Turing yet, keep working at it!
Now, if for some reason you want to do what I did, and make an online,
multiplayer RPG in Turing, its just as easy as the multi-user chat program!
But here this, it will be VERY slow for the .NET commands to send all at
once to all the seperate clients. So, online multiplayer graphical RPG's
are NOT going to work out to well, believe me! So if you want to continue with
Turing .NET commands, make a text based RPG or something, where you dont need the
.NET commands to be as fast. (I also did this, lol.) Now the main way you go from
a chat program to a game, is by doing something like this:

[assuming vars are: hp,magic,weapon,armor]
(1) Make it all into one string, instead of just sending a bunch
or seperate information, because its quicker only sending one.
ex. infoToSend:=intstr(hp)+"+"+intstr(magic)+"+"+weapon+"+"+armor
if hp=50,magic=30,weapon="sword",armor="platemail" then it would look like
this:

put infoToSend
50+30+sword+platemail

Now, just send that to the server. The server must pick through this to get the info.
Ok, we now there will be 3 '+' (plus) signs, so we will use this code to get the info:

%% Declares the infoToSend string that receives info from client
var infoToSend : string
%% get : netStream,infoToSend
infoToSend := "50+30+sword+platemail"
%% Declares the hp,magic, etc.
var hp, magic, stringLength, num : int := 1
%% Gets the length of infoToSend, saves value in stringLength
stringLength := length (infoToSend)
var weapon, armor : string
%% Declares an array of 3 integers, which will save where in the
%% string infoToSend that the '+' (plus) signs are located
var plusFound : array 1 .. 3 of int
%% Sets them to a null value of 0
for i : 1 .. 3
    plusFound (i) := 0
end for
%% Goes through the string infoToSend, if it finds a plus, it saves
%% the location in that string as an integer under the array plusFound
%% Then the number in the array plusFound to save the next '+' location
%% in is moved up by one
for i : 1 .. stringLength
    if infoToSend (i) = "+" then
	plusFound (num) := i
	num += 1
    end if
end for
%% Here is how it gets the information using substrings and the plusFound array
%%
%% 12 3 45 6 789...      [etc. 1st char=5,2nd char=0,3rd char=+,etc.]
%% || | || | |||
%% 50 + 30 + sword + platemail            <>plusFound(1)=3
%%    ^    ^       ^                      <>plusFound(2)=6
%%    3    6       12                     <>plusFound(3)=12
%%
%% HP will be located between 1 and the first plus location (3) subtract 1
%% Magic will be located 1 above the first plusFound, and 1 minus the second plusFound
%% Weapon will be located 1 above the second plusFound, and 1 minus the third plusFound
%% Armor will be located 1 above the third plusFound, right up to the length of the string
hp := strint (infoToSend (1 .. (plusFound (1) - 1)))
put "HP: ", hp
magic := strint (infoToSend ((plusFound (1) + 1) .. (plusFound (2) - 1)))
put "Magic: ", magic
weapon := infoToSend ((plusFound (2) + 1) .. (plusFound (3) - 1))
put "Weapon: ", weapon
armor := infoToSend ((plusFound (3) + 1) .. stringLength)
put "Armor: ", armor


And there you go, you send one string of information from client to server,
and the server easily disects it into the information for each user. Now for
multiple users, just create an array of hp's, magic's, weapon's, and armor's.
(I suggest using a record to hold all the variables, and making an array of that
record.)
Well...I might as well cover a few more of the other commands.

Net.LocalAddress
This will display for you your IP address
Net.LocalName
This will display the name your computer is under
Net.CharAvailable (netStream)
Checks if a character is available on the NetStream. (USED WITH the
if statement.

var hostName : string := "www.holtsoft.com"
put Net.HostAddressFromName (hostName)

This will display the IP of the designated host name
var hostAddress:string:="127.0.0.1"
put Net.HostNameFromAddress (hostAddress)

This will display the name the computer is under from a designated IP


Well...I really can't think of much more I can write about, so ill just end it here.
I hope a lot of you found this helpful, and if there are any questions, please feel
free to ask them. (Post them in the message you got this from.)
Thanks for reading my Turing .NET Tutorial!!!
		 ___________________________
		|   _____________________   |
		|  |Written by: DanShadow|  | 
		|  |_____________________|  |
		|                           | 
		|       July 31, 2004       |
	      |     565 Line Tutorial     |
		|___________________________|