AdminMod.de
https://www.adminmod.de/

Textlängen anpassen - Automatische Zeilenumbrüche
https://www.adminmod.de/viewtopic.php?t=4666
Seite 1 von 1

Autor:  Sir Drink a lot [ 20.01.2003, 20:06 ]
Betreff des Beitrags:  Textlängen anpassen - Automatische Zeilenumbrüche

Hi Leute!

Hat jemand ein schönes Wörkarund für mich,
um Messages automatisch immer mit Zeilenumbrüchen zu versehen.

Mir geht das langsam auf den Senkel, dass man immer aufpassen muss.

Beim messagex mit print_tty ist es sogar wirklich kritisch, wenn die Zeilenlänge über 78Zeichen kommt. Dann schmiert der Client ab.

Es geht also um die korrekte Bildschirmausgabe!

Gruß,
SDal

Autor:  Rinde [ 21.01.2003, 14:53 ]
Betreff des Beitrags: 

ich überleg mir mal was heute abend

Autor:  [WING] Black Knight [ 21.01.2003, 15:52 ]
Betreff des Beitrags: 

Konzept steht schon.
Code:
Wenn String>78
String bei Character 78 schneiden. Ersten String in Pruefstring schreiben.
Nach dem letzten Leerzeichen im Pruefstring suchen. Position des Leerzeichens merken.
String an der gemerkten Stelle splitten (String1 und String2)
Result=Result+String1+"^n"
String=String2
Zurück zum Anfang
Result=Result+String
Einge Unterfunktionen sind so nicht als native Funktionen vorhanden. Müsst mal in mein bk_cron schauen. Da solltet Ihr fündig werden.

Autor:  Rinde [ 21.01.2003, 22:02 ]
Betreff des Beitrags: 

code steht auch schon

achtung: die einzigen tests fanden in meinem kopf statt :D
Code:
stock format_lines(Text[],maxlen,linelen = 79) { /* Inserts linebreaks into Text for maxlen characters, so no line gets longer than linelen characters, if possible at a space. Returns length of resulting string. */
    new SayText[];
    new textpos;
    new saytextpos;
    new textlen = min(maxlen,strlen(Text));
    new numtoadd;
    new i;
    while(textlen-textpos > linelen) {
        for(i=textpos+79,i>textpos;--i) {
            if(Text[i] == '^n' || Text[i] == ' ' && textpos == numtoadd) {
                numtoadd = i;
            }
        }
        if(numtoadd == textpos) {
            numtoadd == textpos+linelen-1);
        }
        for(i=textpos;i<numtoadd;i++) {
            SayText[saytextpos++] = Text[i];
        }
        SayText[saytextpos++] = '^n';
        if(Text[numtoadd] == ' ' || Text[numtoadd] == '^n') {
            numtoadd++;
        }
        textpos = numtoadd;
    }
    for(i=textpos;i<textlen;i++) {
        SayText[saytextpos++] = Text[i];
    }
    saytextpos = min(saytextpos,maxlen);
    for(i=0;i<saytextpos;i++) {
        Text[i] = SayText[i];
    }
    Text[saytextpos] = '^0';
    return saytextpos;
}

Autor:  [WING] Black Knight [ 21.01.2003, 23:33 ]
Betreff des Beitrags: 

Meiner auch, aber er ist sogar schon getestet, mit Abfangroutinen und höchst flexibel.
Anbei mal ein Beispielplugin, mit dem man ein Messageex auslöst. Geht gut.
Code:
/* Black Knight's automatischer Zeilenumbruch */

#include <core> 
#include <console> 
#include <string> 
#include <admin> 
#include <adminlib>

/* Splits string at a specific position */
strnsplit(str[],first[],second[],n) {
	new i;
	new maxlen=strlen(str);
	new m=n+1;

	for(i=0; i<=n; i++){
		first[i]=str[i];
	}
	first[n+1]=NULL_CHAR;
	for(i=m;i<=maxlen;i++){ 
		second[i-m]=str[i];
	}
	second[maxlen+1]=NULL_CHAR;

	return 1;
}

/* Looks for the first occurence of "search" and splits string there */
strbreak2(str[], first[], second[], maxlen, search[], number) {
	new i = 0;
	new NullPos = CHAR_INVALID;
	new Quote = FALSE;
	new SpacePos = CHAR_INVALID;
	new merk=0;

	if (maxlen == 0){
		maxlen = strlen(str);
	}
			
	for(i=0; i<maxlen; i++) {
		if (str[i] == QUOTE_CHAR) {
			if (Quote==FALSE) {
				Quote = TRUE;
			}
			else {
				Quote = FALSE;
			}
		}
		else if (str[i] == search[0] && Quote == FALSE) {
			merk++;
			if (merk==number) {
				SpacePos = i;
			}
		}
		else if (str[i] == NULL_CHAR) {
			NullPos = i;
			break;
		}	
	}
	
	if (SpacePos == CHAR_INVALID) {
		strcpy(first, str, maxlen);
		strinit(second);
	}
	else {
		if (NullPos == CHAR_INVALID) {
			NullPos = maxlen + 1;
		}
		for(i=0; i<SpacePos; i++) { 
			first[i] = str[i];
		}
		first[SpacePos] = NULL_CHAR;
		for(i=SpacePos+1; i<NullPos;i++) {
			second[i - SpacePos - 1] = str[i];
		}
		second[NullPos - SpacePos - 1] = NULL_CHAR;
	}
	
	/* Strip out the quotes of the return values. */

	return 1;
}



umbrechen(sString[],Result[],Laenge){
	new Umbruch[3]="^n";
	new PruefString[MAX_DATA_LENGTH];
	new RestString[MAX_DATA_LENGTH];
	new Found[MAX_DATA_LENGTH];
	new NrUmbruch=0;
	new Nummer;

	strinit(Result);

	while(strlen(sString) > Laenge){ 
		strnsplit(sString,PruefString,RestString,Laenge);
		Nummer=strcount(PruefString,' ');
		if(Nummer==0){
			strcpy(Found,PruefString,MAX_DATA_LENGTH);
			strcpy(sString,RestString,MAX_DATA_LENGTH);
		}
		else{
			strbreak2(sString,Found,sString,MAX_DATA_LENGTH," ",Nummer);
		}
		strcat(Result,Found,MAX_DATA_LENGTH);
		strcat(Result,Umbruch,MAX_DATA_LENGTH);
		NrUmbruch++; 
	} 
	strcat(Result,sString,MAX_DATA_LENGTH);

	return NrUmbruch;
}

public messageme(HLCommand,HLData,HLUserName,UserIndex){
	new Msg[MAX_DATA_LENGTH];
	new Msg2[MAX_DATA_LENGTH];
	new Name[MAX_NAME_LENGTH];

	convert_string(HLData,Msg,MAX_DATA_LENGTH);
	convert_string(HLUserName,Name,MAX_NAME_LENGTH);

	umbrechen(Msg,Msg2,78);
	messageex(Name,Msg2,print_tty);

	return PLUGIN_HANDLED;
}

public plugin_init(){
	new STRING_VERSION[MAX_DATA_LENGTH] = "1.0";
	plugin_registerinfo("Umbrechen Testplugin","Testplugin fuer Umbruch",STRING_VERSION);
	plugin_registercmd("admin_msg","messageme",ACCESS_ALL,"Prints message");

	return PLUGIN_CONTINUE; 
}
Rinde, bist Du Dir sicher, dass "^n" nur 1 Zeichen ist? Ich sehe es in den Logs immer ausgeschrieben (z.B. bei Csay). Daher habe ich vermutet, dass erst die HL-Ausgabe daraus ein Steuerzeichen macht. Wenn dem nicht so ist, kann ich meine Routine natürlich massiv vereinfachen. Den ganzen Splitkram habe ich nur wegen der 2 Zeichen gemacht. Letzlich käme ich dann auf eine ähnliche integrierte Funktion wie Du.
Kannst du mal Deine Funktion testen?

Autor:  [WING] Black Knight [ 22.01.2003, 01:00 ]
Betreff des Beitrags: 

OK, funktioniert. :D
Code:
/* Black Knight's automatischer Zeilenumbruch No.2*/

#include <core> 
#include <console> 
#include <string> 
#include <admin> 
#include <adminlib>

/* Splits string at a specific position */
strnsplit(str[],first[],second[],n) {
	new i;
	new maxlen=strlen(str);
	new m=n+1;

	for(i=0; i<=n; i++){
		first[i]=str[i];
	}
	first[n+1]=NULL_CHAR;
	for(i=m;i<=maxlen;i++){ 
		second[i-m]=str[i];
	}
	second[maxlen+1]=NULL_CHAR;

	return 1;
}

umbrechen(sString[],Result[],Laenge){
	new erster[MAX_DATA_LENGTH];
	new zweiter[MAX_DATA_LENGTH];
	new sLaenge,pLaenge;
	new pos=0;
	new j=0;
	new wo=0;
	new i;

	strinit(Result);
	sLaenge=strlen(sString);
	pLaenge=sLaenge;
	while(pLaenge > Laenge || j==10){
		for(i=pos;i<=pos+Laenge;i++){
			if(sString[i]==' '){
				wo=i;
			}
			else if(sString[i]=='^n'){
				wo=i;
				break;
			}
		}
		sString[wo]='^n';
		if(wo==pos){
			strnsplit(sString,erster,zweiter,pos+Laenge-1);
			snprintf(sString,MAX_DATA_LENGTH,"%s^n%s",erster,zweiter);
			sLaenge++;
			wo=pos+Laenge;
		}
		pos=wo+1;
		pLaenge=sLaenge-wo;
		j++;
	}
	strcpy(Result,sString,MAX_DATA_LENGTH);

	return j;
}

public messageme(HLCommand,HLData,HLUserName,UserIndex){
	new Msg[MAX_DATA_LENGTH];
	new Msg2[MAX_DATA_LENGTH];
	new Name[MAX_NAME_LENGTH];

	convert_string(HLData,Msg,MAX_DATA_LENGTH);
	convert_string(HLUserName,Name,MAX_NAME_LENGTH);

	umbrechen(Msg,Msg2,78);
	messageex(Name,Msg2,print_tty);

	return PLUGIN_HANDLED;
}

public plugin_init(){
	new STRING_VERSION[MAX_DATA_LENGTH] = "1.0";
	plugin_registerinfo("Umbrechen Testplugin","Testplugin fuer Umbruch",STRING_VERSION);
	plugin_registercmd("admin_msg","messageme",ACCESS_ALL,"Prints message");

	return PLUGIN_CONTINUE; 
}
Ich musste allerdings einen Split drinlassen, da Wörter mit Überlänge sonst nicht handlebar wären. Die werden zwangsumgebrochen.

Autor:  Sir Drink a lot [ 22.01.2003, 11:33 ]
Betreff des Beitrags: 

Danke Dir. Es funktiniert und ich habe es in mein plugin_sdal_deadsay eingebaut.

Siehe 'PLUGINS'.

Autor:  Rinde [ 22.01.2003, 15:08 ]
Betreff des Beitrags: 

welches, meins oder blacky's? btw ich bin mir sicher, dass ^n ein steuerzeichen ist, da ^ der escape character für diese ist, auch in small. ^n belegt genau wie ^0 oder ^^ nur ein zeichen

/edith: sacht mal, eine messageex-zeile kann inklusive newline-character doch 79 zeichen lang sein, oder?

/edit²: ich habs jetzt selbst nochmal getestet. so hat es sogar funktioniert:
Code:
stock format_lines(Text[],maxlen,linelen = 79) { //Inserts linebreaks into Text for maxlen characters, so no line gets longer than linelen characters, if possible at a space. Returns length of resulting string.
    new SayText[250];
    new textpos;
    new saytextpos;
    new textlen = min(maxlen,strlen(Text));
    new numtoadd;
    new i;
    while(textlen-textpos > linelen) {
        for(i=textpos+79;i>textpos;--i) {
            if(Text[i] == '^n' || Text[i] == ' ' && textpos == numtoadd) {
                numtoadd = i;
            }
        }
        if(numtoadd == textpos) {
            numtoadd = textpos+linelen-1;
        }
        for(i=textpos;i<numtoadd;i++) {
            SayText[saytextpos++] = Text[i];
        }
        SayText[saytextpos++] = '^n';
        if(Text[numtoadd] == ' ' || Text[numtoadd] == '^n') {
            numtoadd++;
        }
        textpos = numtoadd;
    }
    for(i=textpos;i<textlen;i++) {
        SayText[saytextpos++] = Text[i];
    }
    saytextpos = min(saytextpos,maxlen);
    for(i=0;i<saytextpos;i++) {
        Text[i] = SayText[i];
    }
    Text[saytextpos] = '^0';
    return saytextpos;
}

Autor:  [WING] Black Knight [ 22.01.2003, 16:47 ]
Betreff des Beitrags: 

Wenn Du genau geguckt hättest, wäre Dir aufgefallen, dass ich noch eine zweite Routine nachgeschoben habe. Das "^n" wird tatsächlich als EIN Steuerzeichen angesehen. Ergo kann man sich das komplizierte Teilen eines Strings bis auf den Fall zu langer Strings sparen. Das hast Du über die das verschieben des Reststrings realisiert. Im Grunde mache ich nichts anderes, verschiebe die Zwischenergebnisse aber in 2 Variablen.

Ich nehme mal an, dass er meins genommen hat, da das zu dem Zeitpunkt schon funktionstüchtig war.

Autor:  Rinde [ 22.01.2003, 16:55 ]
Betreff des Beitrags: 

ich habs schon gesehen. aber das hält mich nicht davon ab, auch noch meine version zu posten. konkurrenz steigert die qualität :D

Autor:  Sir Drink a lot [ 22.01.2003, 17:49 ]
Betreff des Beitrags: 

nicht streiten, meine Kinder :-)
Ihr seid beide für solche kniffligen Sachen die besten Ansprechpartner.

Obwohl...pusht euch weiter gegenseitig.

Kann ja nur Gutes bei rauskommen. (..Was ich dann wieder abgreifen kann :lol: ...)

Ich muss immer wieder betonen, dass ich solche String Manipulationen (oder Bit-Operationen) nicht so schnell hinbekomme, wie ihr beide. (Wenn ich sie überhaupt hinkriegen würde...)

Weiter so!

Autor:  [WING] Black Knight [ 22.01.2003, 19:39 ]
Betreff des Beitrags: 

Na, na, na...
Wir streiten uns doch gar nicht.

Autor:  Rinde [ 22.01.2003, 20:21 ]
Betreff des Beitrags: 

das will ich aber auch meinen :D

Autor:  Sir Drink a lot [ 01.02.2003, 18:32 ]
Betreff des Beitrags: 

so..wollen wir das mal weiterführen :-)

Ich habe beide Codes mit dem angehängten Plugin ausprobiert.

Leider bekam ich trotzdem einen AMX Error, da die Zeilen zu lang waren.

Ich habe jetzt einen einfachen direkten Umbruch gewählt. Natürlich sähe es schöner aus, wenn er genau bei einem Leerzeichen umbrechen würde.

Ist aber jetzt nicht so schlimm. Ich dachte nur, dass ihr vielleicht bei den oben genannten Codes etwas nicht bedacht habt.

Das Plugin ist ein WINDOWS LOG-READER.

Man beachte, dass er wirklich nur auf Windows-Servern funktioniert und das er nie im richtigen Spielbetrieb eingesetzt werden sollte !!

Mit admin_logload 'Tag.Monat' kann man bis 999 Namen der Log-Dateien von diesem Tag einlesen. Die Logdateien werden durchnummeriert von 0 bis eben 999.

Mit admin_logread 'LogDatei-Nummer' 'Zeilennummer' kann man sich jetzt die gewählte Logdatei aufrufen und durchlesen. Es werden immer max. 10 Zeilen auf einmal angezeigt.

Das Plugin diente nur als Test des ' look_in_dir ' Befehls, da ich diesen bisher noch nie verwendet habe :-) und ob das filesize, readfile ab AM 2.50.51 korrekt funktioniert.

filesize und readfile scheint jetzt einwandfrei zu funktionieren.

Nun denn, wenn ihr Lust habt, könnt ihr ja den 'korrekten Zeilenumbruch' in das Plugin einbauen.

Gruß,
SDal

Autor:  Sir Drink a lot [ 01.02.2003, 19:18 ]
Betreff des Beitrags: 

Euer Code ist ok.

Nach Beratung mit Blacky wurde festgestellt, dass dem selfmessage ein Zeilenumbruch egal ist.

Auch trotz Zeilenumbruch, wird die Gesamtlänge genommen und ein AMX String to long ausgegeben.


Ergo: Man nehme messageex(User,Text,print_console). Da werden die Zeilenumbrüche beachtet!

:-)

Autor:  [WING] Black Knight [ 01.02.2003, 19:33 ]
Betreff des Beitrags: 

Nochmal als Info. In 2.50.51 ist filesize und readfile noch verbugt. Nur die internen Betas haben das bisher behoben.

Autor:  Sir Drink a lot [ 02.02.2003, 04:12 ]
Betreff des Beitrags: 

ups...sorry....ja..

Seite 1 von 1 Alle Zeiten sind UTC+01:00
Powered by phpBB® Forum Software © phpBB Limited
https://www.phpbb.com/