PDA

View Full Version : Guide to Making a Server?


Mooch
09-30-2004, 08:53 AM
Can someone plllleeeasse take just a moment out of their time and reply on how to set up a server. I have so many ideas for it and I WILL be able to keep it up 24/7. I just need that one kind person to help me. I'm preferably looking to start an old world server, but if that can't be done then just setting up the 5.9 is fine with me.

It would mean alot to me if someone could help me and if posted help everyone else looking to make a server. All the guides are either outdated or are half done.. Thanks

Malignus Wingnut
09-30-2004, 09:43 AM
Downloads:

1) MySQL - used for database editing.

http://dev.mysql.com/get/Downloads/MySQL-4.0/mysql-4.0.18-win.zip/from/pick#mirrors


2) EQEmu 5.9 DR1 - Perl Enabled

http://home.comcast.net/~molimo140/59perl.zip


3) Active Perl - Used for writing quests.

Perl 5.8 http://downloads.activestate.com/ActivePerl/Windows/5.8/ActivePerl-5.8.2.808-MSWin32-x86.msi

AND

NMAKE.exe
http://www-124.ibm.com/developerworks/oss/cvs/jsp/~checkout~/jspformatbean2/Attic/NMAKE.EXE?rev=1.1.1.1&content-type=application/exe


4) Databases:

You said you wanted to create an old world server. The only current old world database is being worked on by the folks at peqserver. Currently the "Classic" database has been released (Nothing but standard EQ, no expansions). This can be downloaded at:

www.peqserver.com

Click on DB Releases, and download 5.8 Classic.

---------------------------------------------------------------

STEP ONE: Installing Stuff

1) Install MySQL, run the program I had you download.

2) Extract the contents of 59perl.zip to C:\eqemu

3) Install Perl 5.8

4) Copy NMAKE.exe (downloaded above) into C:\perl\bin

5) Install IO::Scalar

Open a Command Prompt (Start menu -> run -> type cmd -> hit enter)

type
perl -MCPAN -e shell

It will ask you if you want to configure Manually. Say no.

When that is done type
install IO::Scalar
Once complete it will say Install OK (or something to that effect).

IF YOU GET AN ERROR MESSAGE saying it failed to install, It should say something at the bottom as an alternate method of installing IO::Scalar. Type what it says to. If that doesn't work.. I dont know, because by this point i had it installed successfully.

To make sure IO::Scalar is installed properly, type
perl -MIO::Scalar -e "print 'Installed'"

If it was installed properly, you should see the word "Intalled" on your command prompt.


6) Extract your database that you downloaded to C:\mysql\bin
-----------------------------------------------------

STEP TWO: Setting up your database

1) Go to C:\mysql\bin and run WinMySQLAdmin.exe

A window should pop up asking you for a username and a password. Pick both and write them down, you will need them later.

You can now close this.

2) In C:\mysql\bin, run mysql.exe

Type into the window:

GRANT ALL PRIVILEGES ON * TO Username@localhost IDENTIFIED BY 'Password' WITH GRANT OPTION;

Replace Username with the username you selected above, and Password with the password you selected above.

It should say something like:
Query OK, 1 Rows Affected, 0.0sec

Now type:

Create Database eq;

You can name your database whatever you want (Replace eq with whatever), however for simplicity I amusing eq.

Should say
Query OK, 1 Rows Affected, 0.0sec

Next type:

Use Database eq;

This sets what database is being currently used. All changes made will be made to the database that is being used.

Should say
Database Changed.


Now type:

source PEQ_CLASSIC_058.sql;

Replace PEQ_CLASSIC_058.sql with whatever the database you downloaded happens to be called. If you downloaded the 5.8 classic database, this is the name of it.

Lots and lots of
Query OK, 1 Rows Affected, 0.0sec
Will fly by... Eventually it will stop. At this point you can type

quit

And it will close.

------------------------------------------------------------------

STEP 3: Setting up your EQEmu folder

1) Go to c:\eqemu

Open up DB.ini

Should look like this:
# READ README.TXT!

[Database]
host=
user=
password=
database=


### --- This file tells world.exe what computer mySQL is on. Host should
### --- be left "localhost" unless mysql is on a differant computer than world.exe.

Where it says host=, enter localhost, full line will be host=localhost

where it says user= and password=, enter the username and password you selected when you ran winmysqladmin.exe

Where it says database=, enter the name of the database you created. If you followed this guide exactly, it should read database=eq.

Save and close.

Open up LoginServer.ini

Looks like this:

### --- This file tells world.exe what loginserver to connect to.
### --- Leave the account and password field BLANK.

### --- Public Login is un-supported as is LAN playing. We reccomend using the EQEmu.net Loginserver ALWAYS.

### --- NOTE: Starting 6-1-2002, you can no longer use the word "Server" in worldname.
### --- NOTE2: the word "Server" is added to each server automaticly.

# READ README.TXT

[LoginServer]
loginserver=newlogin1.eqemulator.net
#loginserver2=eqemulator.net
loginport=5994
#loginport2=5996
worldname=
worldaddress=
locked=
account=
password=


[WorldServer]
Defaultstatus=0
Unavailzone=

[ChatChannelServer]
worldshortname=
chataddress=
chatport=

Where it says worldname=, enter the name of your server. Whatever is there is what will show up on server select. Do not put the word Server in your server name, it is automatically added.

Where it says worldaddress=, enter your EXTERNAL IP ADDRESS.

You can find this by going to www.whatismyip.com

Where it says locked=, enter either true or false. This controls whether or not your server shows up as LOCKED on server select. In the locked state, only GM-Admins or higher can log in.

Leave everything else in this file alone.

Save and close.

Open up notepad. Enter the following.

REM: ****Read this first!!!****

REM: This file requires your real IP in the place of "YourIP" when you are connecting
REM: To the EQEmu Loginserver.

REM: When you are using minilogin, Replace all IP Addresses to say 127.0.0.1

REM: If you still get errors try using localhost instead of 127.0.0.1

REM:--------------Start-----------------------
@echo off

if NOT exist spells_us.txt goto NOSPELL

start zone . EXTERNALIP 7995 INTERNALIP
start zone . EXTERNALIP 7996 INTERNALIP
start zone . EXTERNALIP 7997 INTERNALIP
start zone . EXTERNALIP 7998 INTERNALIP
start zone . EXTERNALIP 7999 INTERNALIP
exit
cls

:NOSPELL
echo You did not copy the spells_us.txt from your everquest directory to this one. Please do so or zones will crash on startup.
PAUSE

REM:---------------END------------------------


Replace EXTERNALIP with your external ip address (www.whatismyip.com)

Replace INTERNALIP with your Internal IP address.

To find your internal ip address, open start menu, click on run, type cmd, hit return. When the command prompt comes up, type ipconfig, and hit enter. You will see several things:

IP Address.....................................192.16 8.x.x
Subnet Mask...................................255.255.255 .0
Default Gateway.............................192.169.0.1

Not necessarily in that order. Where it says IP Address, this is your internal ip address.

After you have made those changes, go to save as, select File type: All Files from the drop down menu, and enter the filename Boot5Zones.BAT & save it to C:\eqemu

Close.

-----------------------------------------------------------------------

STEP FOUR: Starting up your server.

1)Run World.exe in your C:\eqemu folder.
2)Run Boot5Zones.BAT.

3) Let them both run...log in and you're ready to connect.

(Make sure your eqhost.txt file is correct (in your Everquest directory. It should read:

[Loginserver]
host=newlogin1.eqemulator.net:5994

---------------------------------------------------------------

Final Notes

IF YOU ARE BEHIND A ROUTER, VIEW THIS THREAD:

http://www.eqemulator.net/forums/viewtopic.php?t=16747

To set yourself as a GM. Log into your server, at least once, dont have to create a character, then log out. Open up a command prompt (start -> run -> type cmd -> hit enter)

type

cd c:\eqemu

then

world.exe flag Username Status

Replace Username with your EQEmu server name (the one you use to log into server select with)

Replace Status with one of the following:

0 - Legit
10 - Semi-Legit
20 - Non-Legit
60 - Guide
80 - GM-Quest Troupe
100 - GM-Admin
150 - GM-Lead Admin
200 - GM-Mgmt <--- SERVER OP, the one you want for yourself.


And thats about it...I wrote this just now, so dont quite know how accurate it is, however it should be very. Good luck.

joshyoowuh
10-03-2004, 07:41 AM
Downloads:
1) MySQL - used for database editing.

http://dev.mysql.com/get/Downloads/MySQL-4.0/mysql-4.0.18-win.zip/from/pick#mirrors


Okay well I wanted to try this cause no matter how I tried the server was always locked on me, however... the download mirrors you gave, all of them do not work (well at least the ones I tried, and I have tried many) I was wondering if you knew another mirror that actually works?

Xabob
10-03-2004, 08:29 AM
0 - Legit
10 - Semi-Legit
20 - Non-Legit
60 - Guide
80 - GM-Quest Troupe
100 - GM-Admin
150 - GM-Lead Admin
200 - GM-Mgmt <--- SERVER OP, the one you want for yourself.

Actully its

0 Normal
10 * Steward *
20 * Apprentice Guide *
50 * Guide *
80 * QuestTroupe *
81 * Senior Guide *
85 * GM-Tester *
90 * EQ Support *
95 * GM-Staff *
100 * GM-Admin *
150 * GM-Lead Admin *
160 * QuestMaster *
170 * GM-Areas *
180 * GM-Coder *
200 * GM-Mgmt *
250 * GM-Impossible <------ the one u want[/code]

sotonin
10-03-2004, 08:31 AM
Downloads:
1) MySQL - used for database editing.

http://dev.mysql.com/get/Downloads/MySQL-4.0/mysql-4.0.18-win.zip/from/pick#mirrors


Okay well I wanted to try this cause no matter how I tried the server was always locked on me, however... the download mirrors you gave, all of them do not work (well at least the ones I tried, and I have tried many) I was wondering if you knew another mirror that actually works?

They all work. You just aren't using them right, or you are having a completely unrelated issue to mysql and for whatever reason in your head "think" it's mysql. Any semi-recent version of mysql will work for emu.

Mooch
11-06-2004, 10:39 AM
Alright for the Install OI::Scarlar*
after i type in perl -MCPAN -e shell

it says:

cpan shell -- CPAN exploration and modules installation (v1.7601)
ReadLine support available (try 'install Bundle::Cpan')

It doesn't ask me if i'd like to manually configure it.

WildcardX
11-07-2004, 04:11 PM
I had the same problem with IO::SCALAR install too. I found what I had to do was go to here: http://search.cpan.org and then type in a search for SCALAR.PM. Choose the first result that comes up, it should be something like IO::SCALAR. Click it then click on the "source" link that is near the top of the page. Select all of that text and copy it into notepad. then save it to c:\perl\lib\io as scalar.pm. Next repeat the search but this time for WRAPTIE.PM. Next click the first hit back, should be something like IO::WRAPTIE.PM. Click the source link that is near the top again and now select all that text and copy it into notepad then save it as c:\perl\lib\io\wraptie.pm. This worked for me atleast. I found this solution in this thread: http://www.eqemulator.net/forums/viewtopic.php?t=17531. Hope it helps you too.

WildcardX
11-07-2004, 04:13 PM
SCALAR.PM is the following text:

package PerlIO::scalar;
our $VERSION = '0.02';
use XSLoader ();
XSLoader::load 'PerlIO::scalar';
1;
__END__

=head1 NAME

PerlIO::scalar - in-memory IO, scalar IO

=head1 SYNOPSIS

my $scalar = '';
...
open my $fh, "<", \$scalar or die;
open my $fh, ">", \$scalar or die;
open my $fh, ">>", \$scalar or die;

or

my $scalar = '';
...
open my $fh, "<:scalar", \$scalar or die;
open my $fh, ">:scalar", \$scalar or die;
open my $fh, ">>:scalar", \$scalar or die;

=head1 DESCRIPTION

A filehandle is opened but the file operations are performed "in-memory"
on a scalar variable. All the normal file operations can be performed
on the handle. The scalar is considered a stream of bytes. Currently
fileno($fh) returns C<undef>.

=head1 IMPLEMENTATION NOTE

C<PerlIO::scalar> only exists to use XSLoader to load C code that
provides support for treating a scalar as an "in memory" file.
One does not need to explicitly C<use PerlIO::scalar>.

=cut





And WRAPTIE.PM is the following:

# SEE DOCUMENTATION AT BOTTOM OF FILE


#------------------------------------------------------------
package IO::WrapTie;
#------------------------------------------------------------
require 5.004; ### for tie
use strict;
use vars qw(@ISA @EXPORT $VERSION);
use Exporter;

# Inheritance, exporting, and package version:
@ISA = qw(Exporter);
@EXPORT = qw(wraptie);
$VERSION = substr q$Revision: 2.102 $, 10;

# Function, exported.
sub wraptie {
IO::WrapTie::Master->new(@_);
}

# Class method; BACKWARDS-COMPATIBILITY ONLY!
sub new {
shift;
IO::WrapTie::Master->new(@_);
}



#------------------------------------------------------------
package IO::WrapTie::Master;
#------------------------------------------------------------

use strict;
use vars qw(@ISA $AUTOLOAD);
use IO::Handle;

# We inherit from IO::Handle to get methods which invoke i/o operators,
# like print(), on our tied handle:
@ISA = qw(IO::Handle);

#------------------------------
# new SLAVE, TIEARGS...
#------------------------------
# Create a new subclass of IO::Handle which...
#
# (1) Handles i/o OPERATORS because it is tied to an instance of
# an i/o-like class, like IO::Scalar.
#
# (2) Handles i/o METHODS by delegating them to that same tied object!.
#
# Arguments are the slave class (e.g., IO::Scalar), followed by all
# the arguments normally sent into that class's TIEHANDLE method.
# In other words, much like the arguments to tie(). :-)
#
# NOTE:
# The thing $x we return must be a BLESSED REF, for ($x->print()).
# The underlying symbol must be a FILEHANDLE, for (print $x "foo").
# It has to have a way of getting to the "real" back-end object...
#
sub new {
my $master = shift;
my $io = IO::Handle->new; ### create a new handle
my $slave = shift;
tie *$io, $slave, @_; ### tie: will invoke slave's TIEHANDLE
bless $io, $master; ### return a master
}

#------------------------------
# AUTOLOAD
#------------------------------
# Delegate method invocations on the master to the underlying slave.
#
sub AUTOLOAD {
my $method = $AUTOLOAD;
$method =~ s/.*:://;
my $self = shift; tied(*$self)->$method(\@_);
}

#------------------------------
# PRELOAD
#------------------------------
# Utility.
#
# Most methods like print(), getline(), etc. which work on the tied object
# via Perl's i/o operators (like 'print') are inherited from IO::Handle.
#
# Other methods, like seek() and sref(), we must delegate ourselves.
# AUTOLOAD takes care of these.
#
# However, it may be necessary to preload delegators into your
# own class. PRELOAD will do this.
#
sub PRELOAD {
my $class = shift;
foreach (@_) {
eval "sub ${class}::$_ { my \$s = shift; tied(*\$s)->$_(\@_) }";
}
}

# Preload delegators for some standard methods which we can't simply
# inherit from IO::Handle... for example, some IO::Handle methods
# assume that there is an underlying file descriptor.
#
PRELOAD IO::WrapTie::Master
qw(open opened close read clearerr eof seek tell setpos getpos);



#------------------------------------------------------------
package IO::WrapTie::Slave;
#------------------------------------------------------------
# Teeny private class providing a new_tie constructor...
#
# HOW IT ALL WORKS:
#
# Slaves inherit from this class.
#
# When you send a new_tie() message to a tie-slave class (like IO::Scalar),
# it first determines what class should provide its master, via TIE_MASTER.
# In this case, IO::Scalar->TIE_MASTER would return IO::Scalar::Master.
# Then, we create a new master (an IO::Scalar::Master) with the same args
# sent to new_tie.
#
# In general, the new() method of the master is inherited directly
# from IO::WrapTie::Master.
#
sub new_tie {
my $self = shift;
$self->TIE_MASTER->new($self,@_); ### e.g., IO::Scalar::Master->new(@_)
}

# Default class method for new_tie().
# All your tie-slave class (like IO::Scalar) has to do is override this
# method with a method that returns the name of an appropriate "master"
# class for tying that slave.
#
sub TIE_MASTER { 'IO::WrapTie::Master' }

#------------------------------
1;
__END__


package IO::WrapTie; ### for doc generator


=head1 NAME

IO::WrapTie - wrap tieable objects in IO::Handle interface

I<This is currently Alpha code, released for comments.
Please give me your feedback!>


=head1 SYNOPSIS

First of all, you'll need tie(), so:

require 5.004;

I<Function interface (experimental).>
Use this with any existing class...

use IO::WrapTie;
use FooHandle; ### implements TIEHANDLE interface

### Suppose we want a "FooHandle->new(&FOO_RDWR, 2)".
### We can instead say...

$FH = wraptie('FooHandle', &FOO_RDWR, 2);

### Now we can use...
print $FH "Hello, "; ### traditional operator syntax...
$FH->print("world!\n"); ### ...and OO syntax as well!

I<OO interface (preferred).>
You can inherit from the IO::WrapTie::Slave mixin to get a
nifty C<new_tie()> constructor...

#------------------------------
package FooHandle; ### a class which can TIEHANDLE

use IO::WrapTie;
@ISA = qw(IO::WrapTie::Slave); ### inherit new_tie()
...


#------------------------------
package main;

$FH = FooHandle->new_tie(&FOO_RDWR, 2); ### $FH is an IO::WrapTie::Master
print $FH "Hello, "; ### traditional operator syntax
$FH->print("world!\n"); ### OO syntax

See IO::Scalar as an example. It also shows you how to create classes
which work both with and without 5.004.


=head1 DESCRIPTION

Suppose you have a class C<FooHandle>, where...

=over 4

=item *

B<FooHandle does not inherit from IO::Handle;> that is, it performs
filehandle-like I/O, but to something other than an underlying
file descriptor. Good examples are IO::Scalar (for printing to a
string) and IO::Lines (for printing to an array of lines).

=item *

B<FooHandle implements the TIEHANDLE interface> (see L<perltie>);
that is, it provides methods TIEHANDLE, GETC, PRINT, PRINTF,
READ, and READLINE.

=item *

B<FooHandle implements the traditional OO interface> of
FileHandle and IO::Handle; i.e., it contains methods like getline(),
read(), print(), seek(), tell(), eof(), etc.

=back


Normally, users of your class would have two options:


=over 4

=item *

B<Use only OO syntax,> and forsake named I/O operators like 'print'.

=item *

B<Use with tie,> and forsake treating it as a first-class object
(i.e., class-specific methods can only be invoked through the underlying
object via tied()... giving the object a "split personality").

=back


But now with IO::WrapTie, you can say:

$WT = wraptie('FooHandle', &FOO_RDWR, 2);
$WT->print("Hello, world\n"); ### OO syntax
print $WT "Yes!\n"; ### Named operator syntax too!
$WT->weird_stuff; ### Other methods!

And if you're authoring a class like FooHandle, just have it inherit
from C<IO::WrapTie::Slave> and that first line becomes even prettier:

$WT = FooHandle->new_tie(&FOO_RDWR, 2);

B<The bottom line:> now, almost any class can look and work exactly like
an IO::Handle... and be used both with OO and non-OO filehandle syntax.


=head1 HOW IT ALL WORKS


=head2 The data structures

Consider this example code, using classes in this distribution:

use IO::Scalar;
use IO::WrapTie;

$WT = wraptie('IO::Scalar',\$s);
print $WT "Hello, ";
$WT->print("world!\n");

In it, the wraptie() function creates a data structure as follows:

* $WT is a blessed reference to a tied filehandle
$WT glob; that glob is tied to the "Slave" object.
| * You would do all your i/o with $WT directly.
|
|
| ,---isa--> IO::WrapTie::Master >--isa--> IO::Handle
V /
.-------------.
| |
| | * Perl i/o operators work on the tied object,
| "Master" | invoking the TIEHANDLE methods.
| | * Method invocations are delegated to the tied
| | slave.
`-------------'
|
tied(*$WT) | .---isa--> IO::WrapTie::Slave
V /
.-------------.
| |
| "Slave" | * Instance of FileHandle-like class which doesn't
| | actually use file descriptors, like IO::Scalar.
| IO::Scalar | * The slave can be any kind of object.
| | * Must implement the TIEHANDLE interface.
`-------------'


I<NOTE:> just as an IO::Handle is really just a blessed reference to a
I<traditional> filehandle glob... so also, an IO::WrapTie::Master
is really just a blessed reference to a filehandle
glob I<which has been tied to some "slave" class.>


=head2 How wraptie() works

=over 4

=item 1.

The call to function C<wraptie(SLAVECLASS, TIEARGS...)> is
passed onto C<IO::WrapTie::Master::new()>.
Note that class IO::WrapTie::Master is a subclass of IO::Handle.

=item 2.

The C<IO::WrapTie::Master::new> method creates a new IO::Handle object,
reblessed into class IO::WrapTie::Master. This object is the I<master>,
which will be returned from the constructor. At the same time...

=item 3.

The C<new> method also creates the I<slave>: this is an instance
of SLAVECLASS which is created by tying the master's IO::Handle
to SLAVECLASS via C<tie(HANDLE, SLAVECLASS, TIEARGS...)>.
This call to C<tie()> creates the slave in the following manner:

=item 4.

Class SLAVECLASS is sent the message C<TIEHANDLE(TIEARGS...)>; it
will usually delegate this to C<SLAVECLASS::new(TIEARGS...)>, resulting
in a new instance of SLAVECLASS being created and returned.

=item 5.

Once both master and slave have been created, the master is returned
to the caller.

=back


=head2 How I/O operators work (on the master)

Consider using an i/o operator on the master:

print $WT "Hello, world!\n";

Since the master ($WT) is really a [blessed] reference to a glob,
the normal Perl i/o operators like C<print> may be used on it.
They will just operate on the symbol part of the glob.

Since the glob is tied to the slave, the slave's PRINT method
(part of the TIEHANDLE interface) will be automatically invoked.

If the slave is an IO::Scalar, that means IO::Scalar::PRINT will be
invoked, and that method happens to delegate to the C<print()> method
of the same class. So the I<real> work is ultimately done by
IO::Scalar::print().


=head2 How methods work (on the master)

Consider using a method on the master:

$WT->print("Hello, world!\n");

Since the master ($WT) is blessed into the class IO::WrapTie::Master,
Perl first attempts to find a C<print()> method there. Failing that,
Perl next attempts to find a C<print()> method in the superclass,
IO::Handle. It just so happens that there I<is> such a method;
that method merely invokes the C<print> i/o operator on the self object...
and for that, see above!

But let's suppose we're dealing with a method which I<isn't> part
of IO::Handle... for example:

my $sref = $WT->sref;

In this case, the intuitive behavior is to have the master delegate the
method invocation to the slave (now do you see where the designations
come from?). This is indeed what happens: IO::WrapTie::Master contains
an AUTOLOAD method which performs the delegation.

So: when C<sref()> can't be found in IO::Handle, the AUTOLOAD method
of IO::WrapTie::Master is invoked, and the standard behavior of
delegating the method to the underlying slave (here, an IO::Scalar)
is done.

Sometimes, to get this to work properly, you may need to create
a subclass of IO::WrapTie::Master which is an effective master for
I<your> class, and do the delegation there.




=head1 NOTES

B<Why not simply use the object's OO interface?>
Because that means forsaking the use of named operators
like print(), and you may need to pass the object to a subroutine
which will attempt to use those operators:

$O = FooHandle->new(&FOO_RDWR, 2);
$O->print("Hello, world\n"); ### OO syntax is okay, BUT....

sub nope { print $_[0] "Nope!\n" }
X nope($O); ### ERROR!!! (not a glob ref)


B<Why not simply use tie()?>
Because (1) you have to use tied() to invoke methods in the
object's public interface (yuck), and (2) you may need to pass
the tied symbol to another subroutine which will attempt to treat
it in an OO-way... and that will break it:

tie *T, 'FooHandle', &FOO_RDWR, 2;
print T "Hello, world\n"; ### Operator is okay, BUT...

tied(*T)->other_stuff; ### yuck! AND...

sub nope { shift->print("Nope!\n") }
X nope(\*T); ### ERROR!!! (method "print" on unblessed ref)


B<Why a master and slave?
Why not simply write FooHandle to inherit from IO::Handle?>
I tried this, with an implementation similar to that of IO::Socket.
The problem is that I<the whole point is to use this with objects
that don't have an underlying file/socket descriptor.>.
Subclassing IO::Handle will work fine for the OO stuff, and fine with
named operators I<if> you tie()... but if you just attempt to say:

$IO = FooHandle->new(&FOO_RDWR, 2);
print $IO "Hello!\n";

you get a warning from Perl like:

Filehandle GEN001 never opened

because it's trying to do system-level i/o on an (unopened) file
descriptor. To avoid this, you apparently have to tie() the handle...
which brings us right back to where we started! At least the
IO::WrapTie mixin lets us say:

$IO = FooHandle->new_tie(&FOO_RDWR, 2);
print $IO "Hello!\n";

and so is not I<too> bad. C<:-)>


=head1 WARNINGS

Remember: this stuff is for doing FileHandle-like i/o on things
I<without underlying file descriptors>. If you have an underlying
file descriptor, you're better off just inheriting from IO::Handle.

B<Be aware that new_tie() always returns an instance of a
kind of IO::WrapTie::Master...> it does B<not> return an instance
of the i/o class you're tying to!

Invoking some methods on the master object causes AUTOLOAD to delegate
them to the slave object... so it I<looks> like you're manipulating a
"FooHandle" object directly, but you're not.

I have not explored all the ramifications of this use of tie().
I<Here there be dragons>.


=head1 VERSION

$Id: WrapTie.pm,v 2.102 2001/08/17 02:06:33 eryq Exp $


=head1 AUTHOR

Eryq (F<eryq@zeegee.com>).
President, ZeeGee Software Inc (F<http://www.zeegee.com>).

=cut

WildcardX
11-07-2004, 06:34 PM
Actually, Mooch, even though it appears I got the IO::Scalar to install correctly, I am finding that it is, in fact, not installed correctly... grrr ... Go read this thread for more details... http://www.eqemulator.net/forums/viewtopic.php?p=106064#106064