Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

forced_anon chat

Name: Anonymous 2007-12-04 23:50

Imagine this: you load up a 4chan chat page, and you're connected to another user to chat one on one. Completely at random, with no traces of identity whatsoever. That's it. There could be a button to get a new person if you really don't like who you're talking to or you've seen them before, or you could just hit F5. In the true spirit of Anonymous, you could talk about anything in complete freedom.

I think that could be pretty awesome (and also pretty fail, but such is the way of all things chan), and it's an idea that I've had in the back of my mind for a while. I don't have the wherewithal to make it happen, however, so by /img/'s recommendation I'm here pitching it to /prog/ in the hope that someone will get inspired and make this happen. I'd really like to see it made real. I have to imagine that it would be very simple to make, although finding a good host and getting people to use it is another matter.

Anyone's interest piqued?

Name: 131 2007-12-11 1:37

New server: telnet://213.10.200.234:20656/
Does one-to-one chat, heavily modified version of >>131.

-module( server ).
-export( [ start/1, responder/1, listen/5, client/2,
    client_listen/2, client_mainloop/4 ] ).

start( Port )
    ->
    % Start up the responder so messages can get sent to it.
    PID_Responder = spawn( server, responder, [ [] ] ),

    % Create the server socket and start the server
    case gen_tcp:listen( Port, [ list, { active, false }, { packet, line } ] ) of
        { ok, ServSock }
            ->
            { ok, Port } = inet:port( ServSock ),
            io:format( "Listening on port ~w.~n", [ Port ] ),
            listen( ServSock, PID_Responder, invalid, 0, [] );
        { error, Reason }
            ->
            { error, Reason }
    end
    .

listen( ServerSock, PID_Responder, LastIP, IPtimes, BannedIPs )
    ->
    % Grab the client attempting to connect
    case gen_tcp:accept( ServerSock, 5 * 60 * 1000 ) of
        { ok, ClientSock }
            ->
            % IP checking and banning
            { ok, { IP, _ } } = inet:peername( ClientSock ),
            io:format( "Client connected from ~p!~n", [ IP ] ),
            case lists:member(IP, BannedIPs) of
                true
                    ->
                    gen_tcp:send( ClientSock, "B&\n" ),
                    gen_tcp:close( ClientSock ),
                    listen( ServerSock, PID_Responder, IP, 0, BannedIPs );
                false
                    ->
                    % Set up the thread to listen for that client
                    spawn( server, client, [ClientSock, PID_Responder] ),

                    case IP == LastIP of
                        true
                            ->
                            case IPtimes < 10 of
                                true
                                    ->
                                    listen( ServerSock, PID_Responder, IP, IPtimes + 1, BannedIPs );
                                false
                                    ->
                                    listen( ServerSock, PID_Responder, IP, 0, [ IP | BannedIPs ] )
                            end
                            ;
                        false
                            ->
                            listen( ServerSock, PID_Responder, IP, 0, BannedIPs )
                    end
             end
             ;
        Other
            ->
            io:format( "gen_tcp:accept returned ~p. Quitting.~n", [ Other ] )
    end
    .

client( ClientSock, PID_Responder )
    ->
    % Welcome message
    gen_tcp:send( ClientSock,
"HAVE YOU READ YOUR SICP TODAY?

Use /next to ditch current chatpartner.
Use /echo to toggle echoing.

Waiting for a chatter...\n"),

    % Make thread to handle connection
    spawn( server, client_listen, [ ClientSock, self() ] ),

    % Add to list of available chatters
    PID_Responder ! { add_client, self() },

    % Go into the main loop
    client_mainloop( ClientSock, PID_Responder, nope, false )
    .

client_mainloop( ClientSock, PID_Responder, Otherperson, Echo )
    ->
    receive
        { toggle_echo }
            ->
            gen_tcp:send( ClientSock,
                io_lib:format("Echo mode set to ~p~n", [ not Echo ] )),

            client_mainloop( ClientSock, PID_Responder, Otherperson, not Echo );

        { die }
            ->
            case Otherperson of
                nope
                ->
                    ok;
                PID
                ->
                    PID ! { disconnected }
            end
            ,
            PID_Responder ! { remove_client, self() },

            % Loop
            client_mainloop( ClientSock, PID_Responder, nope, Echo );

        { removed }
            ->
            % We have been removed. No looping, so it exits
           ok;

        { disconnected }
            ->
            % Other party disconnected
            gen_tcp:send( ClientSock, "Disconnected...\n" ),

            % Get back in the available list
            PID_Responder ! { add_client, self() },
           
            % Loop
            client_mainloop( ClientSock, PID_Responder, nope, Echo );

        { connected, PID }
            ->
            io:format("~p connected to ~p~n", [self(), PID]),
            % We got connected
            gen_tcp:send( ClientSock, "Connected to a chatter.\n\n" ),
            % Loop
            client_mainloop( ClientSock, PID_Responder, PID, Echo );

        { disconnect }
            ->
            case Otherperson of
                nope
                    ->
                    ok;
                PID
                    ->
                    PID    ! { disconnected },
                    self() ! { disconnected }
            end
            ,

            % Loop
            client_mainloop( ClientSock, PID_Responder, Otherperson, Echo );

        { message, Message }
            ->
            gen_tcp:send( ClientSock, io_lib:format("<Anonymous> ~s~n", [ Message ] ) ),

            % Loop
            client_mainloop( ClientSock, PID_Responder, Otherperson, Echo );

        { send_message, Message }
            ->
            case Otherperson of
                nope
                    ->
                    ok;
                PID
                    ->
                    case Echo of
                        true
                            ->
                            gen_tcp:send( ClientSock,
                            io_lib:format("<Me> ~s~n", [ Message ] ) );
                        false
                            ->
                            ok
                    end
                    ,
                    PID ! { message, Message }
            end
            ,

            % Loop
            client_mainloop( ClientSock, PID_Responder, Otherperson, Echo )
    end
    .

isprintable( Character )
    ->
    Character >= 32 andalso Character =< 126
    .

client_listen( ClientSock, ClientPID )
    ->
    % Just wait for something to happen.
    case gen_tcp:recv( ClientSock, 0 ) of
        { ok, RawMsg }
            ->
            Msg = lists:filter( fun isprintable/1, RawMsg ),

            case lists:sublist(Msg, 5) of
                "/next"
                    ->
                    ClientPID ! { disconnect };

                "/echo"
                    ->
                    ClientPID ! { toggle_echo };

                _
                    ->
                    ClientPID ! { send_message, Msg }
            end
            ,

            % Loop
            client_listen( ClientSock, ClientPID );

        { error, _ }
            ->
            gen_tcp:close(ClientSock),
            ClientPID ! { die }
    end
    .

random2( Max )
    ->
    % Get two random numbers 1 <= x <= Max
    Random1 = random:uniform( Max ),
    Random2 = random:uniform( Max ),
    case Random1 == Random2 of
        true
            ->
            random2( Max );
        false
            ->
            {Random1, Random2}
    end
    .

connect_clients( AvailableList )
    ->
    io:format("Available: ~p~n", [ AvailableList ]),
    Length = length( AvailableList ),
    case Length < 2 of
        true
            ->
            AvailableList;
        false
            ->
            {Random1, Random2} = random2( Length ),
            Elem1 = lists:nth( Random1, AvailableList),
            Elem2 = lists:nth( Random2, AvailableList),
            io:format("Connecting ~p and ~p~n", [Elem1, Elem2]),
            Elem1 ! { connected, Elem2 },
            Elem2 ! { connected, Elem1 },
            connect_clients(
                lists:delete( Elem1, lists:delete( Elem2, AvailableList ) )
            )
    end
    .

responder( AvailableList )
    ->
    % Message handler
    receive
        { remove_client, ClientPID }
            ->
            io:format( "remove_client ~p~n", [ ClientPID ] ),
            % Remove the entry from the list, if it exists.
            NewAvailableList = lists:delete( ClientPID, AvailableList ),

            % Callback to try to avoid synchronization issues
            ClientPID ! {removed},

            % Loop
            responder( NewAvailableList );

        { add_client, ClientPID }
            ->
            io:format( "add_client ~p~n", [ ClientPID ] ),

            % Add the client into the list and try to connect client pairs
            NewAvailableList = connect_clients( [ ClientPID | AvailableList ] ),

            % Loop
            responder( NewAvailableList )
    end
    .

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List