func SendEventWithRewrite(
	ctx context.Context, rsAPI RoomserverInternalAPI, state *gomatrixserverlib.RespState,
	event gomatrixserverlib.HeaderedEvent, haveEventIDs map[string]bool,
) error {
	isCurrentState := map[string]struct{}{}
	for _, se := range state.StateEvents {
		isCurrentState[se.EventID()] = struct{}{}
	}

	authAndStateEvents, err := state.Events()
	if err != nil {
		return err
	}

	var ires []InputRoomEvent
	var stateIDs []string

	// This function generates three things:
	// A - A set of "rewrite" events, which will form the newly rewritten
	//     state before the event, which includes every rewrite event that
	//     came before it in its state
	// B - A set of "outlier" events, which are auth events but not part
	//     of the rewritten state
	// C - A "new" event, which include all of the rewrite events in its
	//     state
	for _, authOrStateEvent := range authAndStateEvents {
		if authOrStateEvent.StateKey() == nil {
			continue
		}
		if haveEventIDs[authOrStateEvent.EventID()] {
			continue
		}
		if event.StateKey() == nil {
			continue
		}

		// We will handle an event as if it's an outlier if one of the
		// following conditions is true:
		storeAsOutlier := false
		if _, ok := isCurrentState[authOrStateEvent.EventID()]; !ok {
			// The event is an auth event and isn't a part of the state set.
			// We'll send it as an outlier because we need it to be stored
			// in case something is referring to it as an auth event.
			storeAsOutlier = true
		}

		if storeAsOutlier {
			ires = append(ires, InputRoomEvent{
				Kind:         KindOutlier,
				Event:        authOrStateEvent.Headered(event.RoomVersion),
				AuthEventIDs: authOrStateEvent.AuthEventIDs(),
			})
			continue
		}

		// If the event isn't an outlier then we'll instead send it as a
		// rewrite event, so that it'll form part of the rewritten state.
		// These events will go through the membership and latest event
		// updaters and we will generate output events, but they will be
		// flagged as non-current (i.e. didn't just happen) events.
		// Each of these rewrite events includes all of the rewrite events
		// that came before in their StateEventIDs.
		ires = append(ires, InputRoomEvent{
			Kind:          KindRewrite,
			Event:         authOrStateEvent.Headered(event.RoomVersion),
			AuthEventIDs:  authOrStateEvent.AuthEventIDs(),
			HasState:      true,
			StateEventIDs: stateIDs,
		})

		// Add the event ID into the StateEventIDs of all subsequent
		// rewrite events, and the new event.
		stateIDs = append(stateIDs, authOrStateEvent.EventID())
	}

	// Send the final event as a new event, which will generate
	// a timeline output event for it. All of the rewrite events
	// that came before will be sent as StateEventIDs, forming a
	// new clean state before the event.
	ires = append(ires, InputRoomEvent{
		Kind:          KindNew,
		Event:         event,
		AuthEventIDs:  event.AuthEventIDs(),
		HasState:      true,
		StateEventIDs: stateIDs,
	})

	return SendInputRoomEvents(ctx, rsAPI, ires)
}
// SendEventWithRewrite writes an event with KindNew to the roomserver along
// with a number of rewrite and outlier events for state and auth events
// respectively.
SendEventWithRewrite writes an event with KindNew to the roomserver along
with a number of rewrite and outlier events for state and auth events
respectively.
// SendEventWithRewrite writes an event with KindNew to the roomserver along // with a number of rewrite and outlier events for state and auth events // respectively .
func SendEventWithRewrite(
	ctx context.Context, rsAPI RoomserverInternalAPI, state *gomatrixserverlib.RespState,
	event gomatrixserverlib.HeaderedEvent, haveEventIDs map[string]bool,
) error {
	isCurrentState := map[string]struct{}{}
	for _, se := range state.StateEvents {
		isCurrentState[se.EventID()] = struct{}{}
	}
	authAndStateEvents, err := state.Events()
	if err != nil {
		return err
	}
	var ires []InputRoomEvent
	var stateIDs []string
	for _, authOrStateEvent := range authAndStateEvents {
		if authOrStateEvent.StateKey() == nil {
			continue
		}
		if haveEventIDs[authOrStateEvent.EventID()] {
			continue
		}
		if event.StateKey() == nil {
			continue
		}
		storeAsOutlier := false
		if _, ok := isCurrentState[authOrStateEvent.EventID()]; !ok {
			storeAsOutlier = true
		}
		if storeAsOutlier {
			ires = append(ires, InputRoomEvent{
				Kind:         KindOutlier,
				Event:        authOrStateEvent.Headered(event.RoomVersion),
				AuthEventIDs: authOrStateEvent.AuthEventIDs(),
			})
			continue
		}
		ires = append(ires, InputRoomEvent{
			Kind:          KindRewrite,
			Event:         authOrStateEvent.Headered(event.RoomVersion),
			AuthEventIDs:  authOrStateEvent.AuthEventIDs(),
			HasState:      true,
			StateEventIDs: stateIDs,
		})
		stateIDs = append(stateIDs, authOrStateEvent.EventID())
	}
	ires = append(ires, InputRoomEvent{
		Kind:          KindNew,
		Event:         event,
		AuthEventIDs:  event.AuthEventIDs(),
		HasState:      true,
		StateEventIDs: stateIDs,
	})
	return SendInputRoomEvents(ctx, rsAPI, ires)
}
func SendEventWithRewrite ( ctx context . Context , rsAPI RoomserverInternalAPI , state * gomatrixserverlib . RespState , event gomatrixserverlib . HeaderedEvent , haveEventIDs map [ string ] bool , ) error { isCurrentState := map [ string ] struct { } { } for _ , se := range state . StateEvents { isCurrentState [ se . EventID ( ) ] = struct { } { } } authAndStateEvents , err := state . Events ( ) if err != nil { return err } var ires [ ] InputRoomEvent var stateIDs [ ] string for _ , authOrStateEvent := range authAndStateEvents { if authOrStateEvent . StateKey ( ) == nil { continue } if haveEventIDs [ authOrStateEvent . EventID ( ) ] { continue } if event . StateKey ( ) == nil { continue } storeAsOutlier := false if _ , ok := isCurrentState [ authOrStateEvent . EventID ( ) ] ; ! ok { storeAsOutlier = true } if storeAsOutlier { ires = append ( ires , InputRoomEvent { Kind : KindOutlier , Event : authOrStateEvent . Headered ( event . RoomVersion ) , AuthEventIDs : authOrStateEvent . AuthEventIDs ( ) , } ) continue } ires = append ( ires , InputRoomEvent { Kind : KindRewrite , Event : authOrStateEvent . Headered ( event . RoomVersion ) , AuthEventIDs : authOrStateEvent . AuthEventIDs ( ) , HasState : true , StateEventIDs : stateIDs , } ) stateIDs = append ( stateIDs , authOrStateEvent . EventID ( ) ) } ires = append ( ires , InputRoomEvent { Kind : KindNew , Event : event , AuthEventIDs : event . AuthEventIDs ( ) , HasState : true , StateEventIDs : stateIDs , } ) return SendInputRoomEvents ( ctx , rsAPI , ires ) }
SendEventWithRewrite writes an event with KindNew to the roomserver along
with a number of rewrite and outlier events for state and auth events
respectively.
SendEventWithRewrite writes an event with KindNew to the roomserver along with a number of rewrite and outlier events for state and auth events respectively .
// This function generates three things: // A - A set of "rewrite" events, which will form the newly rewritten //     state before the event, which includes every rewrite event that //     came before it in its state // B - A set of "outlier" events, which are auth events but not part //     of the rewritten state // C - A "new" event, which include all of the rewrite events in its //     state // We will handle an event as if it's an outlier if one of the // following conditions is true: // The event is an auth event and isn't a part of the state set. // We'll send it as an outlier because we need it to be stored // in case something is referring to it as an auth event. // If the event isn't an outlier then we'll instead send it as a // rewrite event, so that it'll form part of the rewritten state. // These events will go through the membership and latest event // updaters and we will generate output events, but they will be // flagged as non-current (i.e. didn't just happen) events. // Each of these rewrite events includes all of the rewrite events // that came before in their StateEventIDs. // Add the event ID into the StateEventIDs of all subsequent // rewrite events, and the new event. // Send the final event as a new event, which will generate // a timeline output event for it. All of the rewrite events // that came before will be sent as StateEventIDs, forming a // new clean state before the event.